关于位操作:是否可以在C#中执行循环移位?

关于位操作:是否可以在C#中执行循环移位?

Is there a way to perform a circular bit shift in C#?

我知道以下内容是正确的

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

但是,如果您移动得太远,这些位就会掉到末端。这种情况的发生与您使用的整数大小有关。

是否可以执行移位操作,以使位旋转到另一侧?我正在寻找一个操作,而不是for循环。


如果知道类型的大小,则可以执行以下操作:

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

...,将循环移位32位值。

循环左移n位,在a位变量上:

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

@注释,似乎C#确实对有符号值的高位进行了不同的处理。我在这里找到了一些信息。我还更改了示例以使用uint。


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

1
2
3
4
private UInt32 RotateLeft(UInt32 x, Byte n)
{
      return UInt32((x << n) | (x >> (32 - n)));
}

从.NET Core 3.0开始,还有BitOperations.RotateLeft()BitOperations.RotateRight(),因此您可以使用

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

之类的东西。在以前的版本中,可以在Microsoft中使用BitRotator.RotateLeft()BitRotator.RotateRight()。 VisualStudio.Utilities


仅供参考,这两个函数可以完美地旋转1 / 2word的位:

1
2
3
4
5
6
7
8
9
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;
}

很容易将其扩展为任何给定大小。


最著名的应用是解决约瑟夫斯(Josephus)问题(如"具体数学"中所述,请参见http://oeis.org/A006257)。这基本上是一个没有明显应用的难题。在此视频中,我演示了二阶约瑟夫斯问题和完整平衡树之间的联系。它仍然不是应用程序,但是朝着正确的方向稍微移动。


我不得不承认,我只是搜索了\\\\" C#位旋转\\\\",并找到了一个指向带有Java类的页面的链接,该页面很容易适应C#

I在Google图书中也发现了这一点,它是具有类似行为的C函数


推荐阅读