39

私は次のことが真実であることを知っています

int i = 17; //binary 10001
int j = i << 1; //decimal 34, binary 100010

ただし、シフトしすぎると、ビットが端から落ちます。これがどこで発生するかは、使用している整数のサイズの問題です。

ビットが反対側に回転するようにシフトを実行する方法はありますか? forループではなく、単一の操作を探しています。

4

5 に答える 5

51

タイプのサイズがわかっている場合は、次のようにすることができます。

uint i = 17;
uint j = i << 1 | i >> 31;

... 32 ビット値の循環シフトを実行します。

ab ビット変数で、左 n ビットを巡回シフトする一般化として、次のようにします。

/*some unsigned numeric type*/ input = 17;
var result = input  << n | input  >> (b - n);


@コメント、C#は符号付き値の上位ビットを異なる方法で処理しているようです。私はこれに関するいくつかの情報を見つけましたhere . また、uint を使用するように例を変更しました。

于 2008-08-29T19:57:17.847 に答える
11

1 年前、私は卒業論文のために MD4 を実装しなければなりませんでした。これは、UInt32 を使用した循環ビット シフトの実装です。

private UInt32 RotateLeft(UInt32 x, Byte n)
{
      return UInt32((x << n) | (x >> (32 - n)));
}
于 2008-10-09T02:42:54.487 に答える
4

それを行う方法の参考として、これらの 2 つの関数は 1/2 ワードのビットをローテーションするのに完全に機能します。

static public uint ShiftRight(uint z_value, int z_shift)
{
    return ((z_value >> z_shift) | (z_value << (16 - z_shift))) & 0x0000FFFF;
}

static public uint ShiftLeft(uint z_value, int z_shift)
{
    return ((z_value << z_shift) | (z_value >> (16 - z_shift))) & 0x0000FFFF;
}

任意のサイズに拡張するのは簡単です。

于 2009-06-25T06:43:43.787 に答える