我一直试图让这个工作好几天,我已经阅读了一千个指南和人们的问题,但是,我仍然无法找到一种正确的方法。
我想要做的是将位旋转到左边,这是一个例子。
原始编号= 10000001 = 129 我需要的是= 00000011 = 3
我必须将这些位旋转一定时间(这取决于用户输入的内容),这就是我所做的:
byte b = (byte)129;
byte result = (byte)((byte)b << 1);
Console.WriteLine(result);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
当我尝试将(&lt;&lt;)运算符与该数字一起使用时,它导致错误(OverflowException)的问题(请注意,如果我将第一位的数字设置为0;示例:3 = 00000011;它按预期工作,结果返回6。
问题是,如果第一位是1,它会给我(OverflorException)错误。我知道这不是旋转,它只是一个移位,第一位消失,在字节结束时弹出一个0,然后我可以用OR 000000001操作改变它使它成为1(如果第一位是a 1,如果是0,我就把它留在那里。)
有什么想法吗?提前谢谢!
答案 0 :(得分:8)
你得到一个溢出异常,因为你在一个检查过的上下文中操作,显然。
您可以通过将代码置于未经检查的上下文中来解决这个问题 - 或者只是确保您不会对可能超过255的值执行强制转换回byte
。例如:< / p>
int shifted = b << rotateLeftBits;
int highBits = shifted & 0xff;
int lowBits = shifted >> 8; // Previously high bits, rotated
byte result = (byte) (highBits | lowBits);
这适用于最大8的旋转尺寸。对于更大的尺寸,只需使用rotateLeftBits % 8
(如果您有时可能想要向右旋转,则标准化为非负数)。
答案 1 :(得分:4)
<<
是一个移位运算符,而非旋转运算符。
如果要旋转,可以使用(使用合适的角色):
b = (b >> 7) | ((b & 0x7f) << 1);
第一部分将最左边的部分向下移动到最右边,第二部分将所有其他部分向左移动。
使用or
|
将{{1}}组合在一起。
答案 2 :(得分:0)
感谢您的回答!
在我发布这篇文章后不久,我想出了一个解决这个问题的想法,让我告诉你(在你问之前,它有效!):
byte b = (byte)129;
b = (byte)((byte)b & 127);
byte result = (byte)((byte)b << 1);
result = (byte)((byte)result | 1);
Console.WriteLine(result);
这样做,删除第一位(如果它是1)它向左移动零(不产生溢出),一旦移位结束,它将0改回1.如果第一位是0,它只会移动零(请注意,这只是整个代码的一部分,因为它部分用西班牙文写成(注释和变量)我怀疑你会理解它的大部分,所以我决定拿出有问题的部分向你们展示!
我仍然会尝试你告诉我的事情,看看它是怎么回事,再次感谢你的回答!
答案 3 :(得分:0)
请尝试此功能 - 向两个方向旋转(8位值的左右旋转)[我没有测试过该功能!]
// just for 8Bit values (byte)
byte rot(byte value, int rotation)
{
rotation %= 8;
int result;
if(rotation < 0)
{
result = value << (8 + rotation);
}
else
{
result = value << rotation;
}
byte[] resultBytes = BitConverter.GetBytes(result);
result = resultBytes[0] | resultBytes[1];
return (byte)result;
}
short rot(short value, int rotation) { ... }
int rot(int value, int rotation) { ... }