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,我就把它留在那里)。

C#向左旋转位溢出问题

显然,由于您在检查过的上下文中操作,因此会出现溢出异常。

您可以通过将代码放在未检查的上下文中来解决这一问题,或者只需确保不对大于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) { ... }