比特代表负数

时间:2009-07-24 04:03:05

标签: c bit-manipulation

这对有符号整数的位表示有疑问。例如,当你想表示-1时,它相当于(+1)的2的补码。所以-1表示为0xFFFFFFF。现在,当我将数字移动31并打印结果时,它将返回-1。

signed int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1

那么有人可以向我解释这些位是如何表示负数的吗?

感谢。

6 个答案:

答案 0 :(得分:10)

当最高位为零时,数字为正。当它为1时,数字为负数。

向右移动的负数继续将“1”移位为最高位以保持数字为负。这就是你得到答案的原因。

有关两个补码的更多信息,请参阅this Stackoverflow question


@Stobor指出一些C实现可以将0转换为高位而不是1. [在维基百科中验证。]在Java中,它可靠地是算术移位。

但提问者给出的输出显示他的编译器正在进行算术移位。

答案 1 :(得分:8)

C标准未定义负(必然符号)整数的右移是否将零(逻辑右移)或符号位(算术右移)移位到最高有效位。这取决于实施选择。

因此,可移植代码可确保它不会对负数执行右移。它可以在移位之前将值转换为相应的无符号值(保证使用逻辑右移,将零置于空出的位),或者确保值为正,或者它容忍输出的变化。 / p>

答案 2 :(得分:1)

这是一个算术移位操作,它保留符号位并移动有符号数的尾数部分。

欢呼声

答案 3 :(得分:1)

基本上有两种类型的右移。无符号右移和有符号右移。无符号右移将使位向右移位,导致最低有效位丢失,最高有效位将被替换为0.使用有符号右移,位向右移位,导致最少重要的一点是丢失,并保留最重要的位。带符号的右移将数字除以2的幂(对应于移位的位数),而无符号移位是逻辑移位操作。

“>>”当操作的数据类型是无符号时,运算符执行无符号右移,并且当操作它的数据类型被签名时,它执行带符号的右移。因此,在执行位操作以获得所需结果之前,您需要做的是将对象转换为无符号整数类型。

答案 4 :(得分:0)

查看two's complement说明。它应该有所帮助。

答案 5 :(得分:0)

编辑:当编写以下内容时,问题中的代码写成:

unsigned int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1

如果unsigned int至少是32位宽,那么你的编译器实际上不允许生成-1作为它的输出(有一点需要注意,你应该将unsigned value转换为int,然后再传递给它printf的)。

因为a是无符号整数,所以为其赋值-1必须赋予它UINT_MAX的值(作为最小的非负值与-1模UINT_MAX + 1一致)。只要unsigned int在您的平台上至少有32位,将无符号数量右移31的结果将是UINT_MAX除以2 ^ 31,这必须适合int。 (如果unsigned int是31位或更短,它可以产生任何它喜欢的东西,因为转移的结果是未指定的。)