我遇到了位移和无符号长的问题。这是我的测试代码:
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的计算以便它返回正确的值。
提前致谢。
答案 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,而是使用即将推出的标准并广泛支持。)