签名号码的右移算子

时间:2014-04-29 06:00:55

标签: c++ c

我正在阅读C中的班次运营商。

右移n位除以2加到n。移动带符号的值可能会失败,因为对于负值,结果永远不会超过-1:-5 >> 3-1而不是0,如-5/8

我的问题是为什么改变签名值可能会失败?

为什么-5 >> 3的值为-1且不为零?

请解释一下。

2 个答案:

答案 0 :(得分:0)

它只是实现定义:

来自5.8 Shift运算符

  

操作数应为整数或无范围的枚举类型   进行整体促销。结果的类型是   晋升的左操作数。如果正确,行为是不确定的   操作数是负数,或大于或等于位的长度   晋升的左操作数

     

[...]

     

如果E1具有有符号类型和负值,则结果值是实现定义的。

答案 1 :(得分:-1)

使用有符号整数进行移位是实现定义的,但是如果您使用的体系结构具有算术移位,则可以非常可靠地使用它进行猜测。

这是因为负数如何存储在计算机中。它被称为二补。要切换二进制补码的符号,请NOT其位并添加1.例如,使用8位整数00011010(26),首先NOT得到{{1}然后你添加1并获得11100101( - 26)。问题来自于设置的最重要的位。如果你移动它在左边放0,那么数字会变为正数,但如果它放1s,那么最低可能结果为11100110,即-1。这就是算术移位的工作原理,当你移动计算机时,会添加与最左边位相同的位。

所以要明确,这就是正在发生的事情(使用8位整数,因为它更容易,在这种情况下大小是任意的):11111111向右移3(所以11111011去离开)并且由于设置了最重要的位3 011 s被插入到顶部,所以得到1为-1。