我有:
(gdb) display/t raw_data[4]<<8
24: /t raw_data[4]<<8 = 1111100000000
(gdb) display/t raw_data[5]
25: /t raw_data[5] = 11100111
(gdb) display/t (raw_data[4]<<8)|raw_data[5]
26: /t (raw_data[4]<<8)|raw_data[5] = 11111111111111111111111111100111
为什么第26行的结果不是0001111111100111
?谢谢。
编辑:更具体地说:
(gdb) display/t raw_data[5]
27: /t raw_data[5] = 11100111
(gdb) display/t 0|raw_data[5]
28: /t 0|raw_data[5] = 11111111111111111111111111100111
为什么第26行的结果不是11100111
您的数据类型是char
,在您的平台上看起来是签名的。条目raw_data[5]
保存的是负数-25。
打印格式t
将数据打印为二进制的无符号整数。当您打印raw_data[5]
时,它被转换为无符号字符213,但只有8位。当对数据进行整数运算时,字符被提升为32位整数。
将负char值-25提升为有符号int当然会产生-25,但是它作为无符号int的表示现在是2^^32 + x
,而作为无符号char的表示现在是2^^8 + x
。这就是32位二进制数开头的所有1的来源。
让我们忽略第一个块,因为第二个块是最小的复制。
还需要注意的是,0 | x
保留了x
的值,但是导致了通常的积分提升。
那么第二个块就不那么意外了。
(gdb) display/t raw_data[5]
27: /t raw_data[5] = 11100111
好的,raw_data[5]
就是int8_t(-25)
(gdb) display/t 0|raw_data[5]
28: /t 0|raw_data[5] = 11111111111111111111111111100111
, 0|raw_data[5]
为int(-25)
。
常数8导致提升为有符号整数,因此您在提升中也看到了符号扩展。将其改为UINT8_C(8)。您需要为宏包含stint .h。