这是关于有符号整数位表示的疑问。例如,当您想要表示-1时,它等同于(+1)的二进制补码。因此,-1表示为0xFFFFFFF。现在,当我将我的数字向左移31位并打印结果时,它返回的值是-1。
signed int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
请问有人可以解释一下负数在比特中如何表示吗?
谢谢。
这是关于有符号整数位表示的疑问。例如,当您想要表示-1时,它等同于(+1)的二进制补码。因此,-1表示为0xFFFFFFF。现在,当我将我的数字向左移31位并打印结果时,它返回的值是-1。
signed int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
请问有人可以解释一下负数在比特中如何表示吗?
谢谢。
当最高位为0时,这个数是正数。当最高位为1时,这个数是负数。
右移负数时,会在最高位继续保留“1”,以保持数字的负性。这就是为什么你得到那样的答案。
关于二进制补码的更多信息,请参见这个Stackoverflow问题。
@Stobor指出,一些C编译器可能把0替换成最高位,而不是1。[在维基百科上验证过。]在Java中,它始终是算术移位。
但是,提问者给出的输出表明他的编译器正在进行算术移位。
SAR
操作码具有此处描述的行为。请参见http://siyobik.info/index.php?module=x86&id=285。 - StoborC标准没有明确规定对负数(必然是有符号的)进行右移操作时是否将零位(逻辑右移)或者符号位(算术右移)移入最高位。这由具体实现决定。
因此,可移植的代码应确保不对负数进行右移操作。要么在移位之前将其转换为相应的无符号值(这可以保证使用逻辑右移,将零填充到空出的位),要么确保该值为正数,要么容忍输出结果的差异。
基本上有两种类型的右移操作。一种是无符号右移,另一种是有符号右移。无符号右移将位向右移动,导致最低有效位丢失,最高有效位被替换为0。有符号右移将位向右移动,导致最低有效位丢失,最高有效位被保留。有符号右移通过2的幂(对应于移动的位数)来除以数字,而无符号移位是一个逻辑移位操作。
">>" 运算符在它所操作的数据类型为无符号时执行无符号右移操作,在它所操作的数据类型为有符号时执行有符号右移操作。因此,您需要在执行位操作之前将对象转换为无符号整数类型,以获得所需的结果。
编辑: 下面的内容是在问题中代码被写成如下时编写的:
unsigned int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1