我正在尝试在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次左右,则数字会正确返回(在一堆零之后)。
我假设一个字母容纳一个大空间,未使用数据的“间隙”为零。我的理解有点受限,所以任何建议都将受到赞赏。有没有办法抛弃那些零?
答案 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)))