8字节有符号值到4字节值(长)

时间:2010-12-09 15:27:17

标签: c

我收到8字节到字节缓冲区[8]的有符号值。 对于所有值,此符号位为第63位。

此值不需要如此大的范围,4个最重要的字节为零。 但我需要这个标志。

如何将此值重新键入标准长(4字节)?

符号位于第63位,所以

signed char my_sign = buffer[7] & 0x80 ? -1 : 0

给我一​​个标志(缓冲区[0]& 0x80?-1:0为其他印度人: - )

signed long my_value = my_sign ? -*(long *)buffer : *(long *)buffer

有更简单的方法吗?

3 个答案:

答案 0 :(得分:2)

假设是big-endian,并且你只想要符号,即输出为-1或0:

long my_value = buffer[1] & 0x80 ? -1 : 0

我觉得强迫ASCII图形增强上述的可理解性。以下是我在buffer

中假设要编号的位的方法
6666555555555544444444443333333333222222222211111111110000000000 (tens)
3210987654321098765432109876543210987654321098765432109876543210 (ones)
[000000][111111][222222][333333][444444][555555][666666][777777] (bytes)

因此,如果您通过两条顶行(数十和一行)垂直读取,则在形成“47”(粗体)的列处,您点击左括号以获取索引为2的字节。由于括号标记最多和最低有效位,这意味着你已经在索引2处击中了字节的MSB。该位在字节内部具有索引7,这意味着它的掩码是1<<< 7,或128,或0x80。

因此,使用表达式buffer[2] & 0x80测试该位。

答案 1 :(得分:2)

8字节值中的负数用什么表示?如果它使用了2的补码,那么你可以依赖于2的补码值可以安全地截断到任意长度这一事实,而无需做任何额外的步骤。只要您没有截断任何“占用”位置,原始值就会被保留。

即。正的8字节值将在较高的“未使用”字节中具有全零,而负值将在较高的“未使用”字节中具有全1。根据字节顺序,您可能不需要执行任何操作:只需使用较低的4个字节即可完成。

那么,再次,用什么表示形式用于负数?你说高阶字节包含零。我们是否应该假设即使是负数也包含零?如果是这样,那么所使用的表示不是2的补码。

答案 2 :(得分:0)

负数存储在2的补码中,这意味着64位-1 = 0xFFFFFFFFFFFFFFFF。如果你只挑出32个最低有效位,你就有0xFFFFFFFF = -1。因此,假设您正在处理32位范围内的数字应该能够以完全相同的方式处理正数和负数。