存储负数

时间:2011-03-29 18:03:28

标签: c

在下面的代码中

int main()
{
int  a = -1;
printf("%d",a>>1);
return 0;
}

为什么输出-1。

6 个答案:

答案 0 :(得分:12)

位移仅在无符号类型上定义,对于已实现定义的有符号类型。 这是R的一个有用的改进..

  

严格来说,它的定义是   只要值是签名类型   积极的,结果没有   溢出,右移是   实现 - 为负面定义   值。另一方面,左移   未定义负值

┌───┬──────────────┬──────────────────────────────────┬────────────────────────┐
│   │ Unsigned     │ Signed, positive                 │ Signed, negative       │
├───┼──────────────┼──────────────────────────────────┼────────────────────────┤
│<< │ well-defined │ well-defined, except on overflow │ undefined behaviour    │
│>> │ well-defined │ well-defined                     │ implementation-defined │
└───┴──────────────┴──────────────────────────────────┴────────────────────────┘

答案 1 :(得分:5)

因为-1是二进制的1111111 ... 111。 a>>1操作将“签署扩展”符号位,因此您再次获得1111111 ... 111。

答案 2 :(得分:1)

大多数编译器选择将有符号数的>>解释为算术移位。因此,由于数字最初是负数(即MSB位为1),在右移后,该位被另一个1替换以保留符号,因此,当你开始时,你最终得到-1。

答案 3 :(得分:0)

有符号值的>>运算符可能会执行算术或逻辑移位,具体取决于编译器。算术移位保留符号位,因此-1(在2-s补码机上,这几天是你将遇到的唯一变种)将在右移时保持-1。 (注意,C标准明确没有指定有符号数上的>>是算术移位还是逻辑移位。但它总是对无符号数进行逻辑移位。)

答案 4 :(得分:0)

有符号值的位移定义与实现有关。检查编译器的文档,了解它如何处理它。

答案 5 :(得分:0)

在内存中有符号整数,如果符号int存储为2的补码,当从内存{%d}读取数据时,它将转换为原始形式,因此这里2的补码-1将存储在内存中,假设整数取2个字节,所以{ {1}}

执行2's complement of -1 is 1111 1111 1111 1111之后它会立即更改a>>1正如我们所知,当从内存中读取数据时,它会再次转换为0补码,所以取0111 1111 1111 1111的2的补码它就像{ {1}}等于-1

注意: 0111 1111 1111 1111数字的2的补码与原始二进制表示2的补码相同仅适用于1000 0000 0000 0001数字。在 C 号码中始终存储为2的补码格式