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 位值的循环移位。

作为循环左移 n 位的概括,在 ab 位变量上:

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


@评论,看来C#确实以不同的方式对待有符号值的高位。我在这里找到了一些关于此的信息。我还将示例更改为使用 uint。

于 2008-08-29T19:57:17.847 回答
11

一年前,我必须为我的本科论文实施 MD4。这是我使用 UInt32 实现的循环位移。

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

从 .NET Core 3.0 及更高版本开始,BitOperations.RotateLeft()BitOperations.RotateRight()就可以使用类似的东西

BitOperations.RotateRight(12, 3);
BitOperations.RotateLeft(34L, 5);

BitRotator.RotateLeft()在以前的版本中,您可以BitRotator.RotateRight()在 Microsoft.VisualStudio.Utilities中使用

于 2020-02-11T02:09:56.310 回答
4

就像如何做的参考一样,这两个函数非常适合旋转 1/2word 的位:

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 回答
1

uinta (32位)旋转位的扩展方法:

public static uint ROR(this uint x, int nbitsShift)
    => (x >> nbitsShift) | (x << (32 - nbitsShift));

public static uint ROL(this uint x, int nbitsShift)
    => (x << nbitsShift) | (x >> (32 - nbitsShift));
于 2021-03-12T01:23:58.083 回答