C ++中循环位移的问题

时间:2012-10-15 01:45:48

标签: c++ bit-manipulation

我正在尝试在C ++中实现循环位移。它有点起作用,除非在某一点之后我得到一堆零。

for (int n=0;n<12;n++) {
    unsigned char x=0x0f;
    x=((x<<n)|(x>>(8-n))); //chars are 8 bits
    cout<<hex<<"0x"<<(int)x<<endl;
}

我的输出是:

0xf
0x1e
0x3c
0x78
0xf0
0xe1
0xc3
0x87
0xf
0x0
0x0
0x0

正如你所看到的,我开始得到0x0而不是预期的0x1e,0x3c等。

如果我将for循环扩展为迭代60次左右,则数字会正确返回(在一堆零之后)。

我假设一个字母容纳一个大空间,未使用数据的“间隙”为零。我的理解有点受限,所以任何建议都将受到赞赏。有没有办法抛弃那些零?

2 个答案:

答案 0 :(得分:9)

以负数换算是未定义的行为。

您从0循环到12,但轮班中有8 - n。所以这将是消极的。

如果你想处理n > 8,你需要将模数乘以8.(假设你想要8位循环移位。)


for (int n=0; n < 12; n++) {
    unsigned char x = 0x0f;
    int shift = n % 8;   //  Wrap modulus
    x = ((x << shift) | (x >> (8 - shift))); //chars are 8 bits
    cout << hex << "0x" << (int)x << endl;
}

答案 1 :(得分:1)

将一个字节向左移动超过7将始终为0。 此外,没有定义负数转移。

为了解决此问题,您必须将班次限制为类型的大小。

基本上:

unsigned char x = 0xf;
int shift = n&7;
x=((x<<shift)|(x>>(8-shift)))