1

この関数に整数 2 を渡し、整数 4 を返します

x = 2;
x = rotateInt('L', x, 1); 

(ビットを 1 だけ左シフト)

例: 00000010 -> 左に 1 回転 -> 00000100

しかし、これを渡すと:

x = rotateInt('R', x, 3); 

64、01000000が返されます

これがコードです。誰かがエラーを修正できますか...ありがとう

int rotateInt(char direction, unsigned int x, int y)
{
    unsigned int mask = 0;
    int num = 0, result = 0;
    int i;

    for (i = 0; i < y; i++)
    {     
        if (direction == 'R')
        {
            if ((x & 1) == 1)     
                x = (x ^ 129);
            else    
                x = x >> 1;
        }
        else if (direction == 'L')
        {
            if ((x & 128) == 1)  
                x = (x ^ 129);   
            else
                x = x << 1;
        }
    }
result = (result ^ x);
return result;   
}
4

7 に答える 7

6

ですから、右シフトと左シフトが何であるかを知っていると仮定します。そして、算術シフトと論理シフトの違いを知っていること。

Cには算術シフトしかありません。論理シフトも回転もしません。うそをつきました。C は unsigned int に対して論理シフトを行います。

回転はまさにそれを行います: これは論理シフトと同じですが、数値の末尾を超えてシフトすると、数字が反対側に「ラップアラウンド」します。例えば

0010右回転は0001です。もう一度右回転すると、 になります1000。参照してください、1整数の反対側にラップアラウンドまたは回転します。

左回転も同様です。0100左回転1000、左回転0001、左回転0010など。

回転は、算術右シフトのように符号ビットを保持しないことに注意してください。

したがって、C には算術シフトしかありません。したがって、「回転」部分を手動で実装する必要があります。では、左回転してみましょう。あなたはしたいでしょう:

  1. 一番左のビットの値をキャプチャします。(0か1か?)
  2. 左シフトを行う
  3. ステップ 1 でキャプチャした内容に基づいて、右端のビット (ステップ 1 で説明したビット (回転する必要がある)) を正しい値に設定します。

右回転の同様の方法を理解できるはずです。

幸運を!

于 2010-10-13T23:15:41.400 に答える
4

受け入れられた答えは非常に素晴らしく、簡単です。

しかし、私は C をリフレッシュするためにいくつかの K&R 演習を行っていたので、この右回転関数を共有したいと思いました。

unsigned int rightRotateBits(unsigned int inputWord, int numberOfBitsToRotate) {
    int bitWidth = sizeof(inputWord) * 8;
    // Rotating 32 bits on a 32-bit integer is the same as rotating 0 bits;
    //   33 bits -> 1 bit; etc.
    numberOfBitsToRotate = numberOfBitsToRotate % bitWidth;

    unsigned int tempWord = inputWord;

    // Rotate input to the right
    inputWord = inputWord >> numberOfBitsToRotate;

    // Build mask for carried over bits
    tempWord = tempWord << (bitWidth - numberOfBitsToRotate);

    return inputWord | tempWord;
}

左回転の場合は、-1 から -31 までの値をbitAmount引数に渡すだけです。

この機能は、効率性/携帯性/コンパクトさよりも、教えやすさ/読みやすさ/シンプルさを優先することに注意してください。

于 2013-02-17T00:53:21.397 に答える
1

誰もこれを実装する方法を教えてくれなかったので、組み込み関数を使用できます。ビジュアル スタジオの場合は、_rotl、_rotl64、_rotr、_rotr64 です。

あ、でもローテーションとシフトは別物です!

于 2010-10-13T23:25:12.993 に答える
0

ビットごとのシフト演算子を見てください。

http://en.wikipedia.org/wiki/Bitwise_operators#Shifts_in_C.2C_C.2B.2B_and_Java

于 2010-10-13T22:48:04.920 に答える
0

右への回転は正しいようです。1 横転してまた左サイドから戻ってきた?

とにかく、ここにあなたの材料があります:

http://tigcc.ticalc.org/doc/keywords.html#if - 'L' か 'R' かを判断するため

http://tigcc.ticalc.org/doc/keywords.html#for - シフト回数のカウント用

http://msdn.microsoft.com/en-us/library/f96c63ed(VS.80).aspx - 実際にシフトするには

行って、それで遊んでください。最終的にはうまくいきます!

于 2010-10-13T23:19:01.377 に答える
-1

を使用することをお勧めしますunsigned int

#define DIR_LEFT 0
#define DIR_RIGHT 1

unsigned int rotateInt(unsigned int in, int amount, byte dir)
{
    return(dir == DIR_RIGHT ? (in >> amount) | ((in & ((0x01 << amount) - 1)) << (sizeof(unsigned int)*8 - amount)) : (in << amount)  | ((in & ~((sizeof(unsigned int)*8*8 - 1) >> amount)));
}
于 2010-10-13T23:22:09.260 に答える