无符号长位移位

时间:2011-05-09 13:10:28

标签: c++ long-integer unsigned

我遇到了位移和无符号长的问题。这是我的测试代码:

char header[4];
header[0] = 0x80;
header[1] = 0x00;
header[2] = 0x00;
header[3] = 0x00;

unsigned long l1 = 0x80000000UL;
unsigned long l2 = ((unsigned long) header[0] << 24) + ((unsigned long) header[1] << 16) + ((unsigned long) header[2] << 8) + (unsigned long) header[3];

cout << l1 << endl;
cout << l2 << endl;

我希望l2的值也是2147483648,但它打印18446744071562067968。我假设第一个字节的位移会导致问题?

希望有人可以解释为什么会失败以及我如何修改l2的计算以便它返回正确的值。

提前致谢。

2 个答案:

答案 0 :(得分:5)

存储在char中的0x80值是签名数量。当您将其转换为更宽的类型时,将对值进行扩展签名以保持与较大类型相同的值。

将第一行中char的类型更改为unsigned char,您将无法进行符号扩展。

要简化您的案例,请运行以下命令:

char c = 0x80
unsigned long l = c
cout << l << endl;

你得到这个输出:

18446744073709551488

-128为64位整数(0x80为-128为8位整数)。

答案 1 :(得分:2)

此处的结果相同(Linux / x86-64,GCC 4.4.5)。行为取决于unsigned long的大小,至少 32位,但可能更大

如果你想要32位,请改用uint32_t(来自标题<stdint.h>;不要使用C ++ 03,而是使用即将推出的标准并广泛支持。)