C#向左旋转位溢出问题
本文关键字:溢出 出问题 旋转 | 更新日期: 2023-09-27 18:00:02
我已经试着让它发挥作用好几天了,我已经阅读了一千本指南和人们的问题,但我仍然找不到正确的方法。
我想做的是向左旋转钻头,这里有一个例子。
原始编号=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);
这个问题是,当我尝试将(<<)运算符与该数字一起使用时,它会导致错误(OverflowException)(注意,如果我输入一个第一位为0的数字;示例:3=0.00000011;它按预期工作,结果返回6。
问题是,如果第一位是1,它会给我(OverflowException)错误。我知道这不是旋转,它只是一个移位,第一个比特消失了,在字节的末尾弹出一个0,然后我可以用OR 000000001运算来改变它,使其成为1(如果第一个比特是1,如果它是0,我就把它留在那里)。
显然,由于您在检查过的上下文中操作,因此会出现溢出异常。
您可以通过将代码放在未检查的上下文中来解决这一问题,或者只需确保不对大于255的值执行返回到byte
的强制转换。例如:
int shifted = b << rotateLeftBits;
int highBits = shifted & 0xff;
int lowBits = shifted >> 8; // Previously high bits, rotated
byte result = (byte) (highBits | lowBits);
这将适用于最大为8的旋转尺寸。对于较大的大小,只需使用rotateLeftBits % 8
(如果有时想要向右旋转,请规格化为非负数)。
<<
是移位运算符,而不是旋转运算符。
如果你想旋转,你可以使用(合适的铸件):
b = (b >> 7) | ((b & 0x7f) << 1);
第一部分将最左边的位移到最右边,第二部分将所有其他位移到左边。
CCD_ 4与CCD_。
感谢您的回答!
在我发表这篇文章后不久,我想出了一个解决这个问题的主意,让我向你展示(在你问之前,它有效!):
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,它只会移动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) { ... }