无符号长和位移位

Unsigned long and bit shifting

本文关键字:无符号      更新时间:2023-10-16

我有一个位移位和无符号长整型的问题。这是我的测试代码:

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 的计算以使其返回正确的值。

提前谢谢。

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

将第一行中的char类型更改为unsigned char,您将不会获得符号扩展。

要简化您的案例中发生的情况,请运行以下命令:

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

你会得到这个输出:

18446744073709551488

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

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

如果你想要正好 32 位,请使用 uint32_t 代替(从标头<stdint.h>;不是在 C++03 中,而是在即将推出的标准中得到广泛支持)。