我正在阅读C中的班次运营商。
右移n位除以2加到n。移动带符号的值可能会失败,因为对于负值,结果永远不会超过-1:-5 >> 3
为-1
而不是0
,如-5/8
。
我的问题是为什么改变签名值可能会失败?
为什么-5 >> 3
的值为-1
且不为零?
请解释一下。
答案 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。