3

我正在尝试在 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 次左右,数字会正确返回(在一堆零之后。)

我假设一个 char 包含一个很大的空间,并且未使用数据的“间隙”为零。我的理解有点有限,所以任何建议都将不胜感激。有没有办法扔掉那些零?

4

2 回答 2

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;
}
于 2012-10-15T01:49:11.233 回答
1

将一个字节左移超过 7 将始终导致 0。此外,未定义移位负数。

为了解决这个问题,您必须将转换限制为类型的大小。

基本上:

unsigned char x = 0xf;
int shift = n&7;
x=((x<<shift)|(x>>(8-shift)))
于 2012-10-15T01:52:46.407 回答