我正在阅读有关C中的移位运算符。有符号数的右移运算符
右移n位除以2提高为n。移位有符号值可能会失败,因为对于负值,结果永远不会超过-1:-5 >> 3
为-1
,而不是0
,如-5/8
。
我的问题是为什么转换有符号值可能会失败?
为什么-5 >> 3
的值是-1
而不是零?
请解释一下。
我正在阅读有关C中的移位运算符。有符号数的右移运算符
右移n位除以2提高为n。移位有符号值可能会失败,因为对于负值,结果永远不会超过-1:-5 >> 3
为-1
,而不是0
,如-5/8
。
我的问题是为什么转换有符号值可能会失败?
为什么-5 >> 3
的值是-1
而不是零?
请解释一下。
它仅仅是实现定义:
从5.8移位运算符
的操作数应为整体的或无作用域枚举类型并且执行 积分促销。结果的类型是 升级的左操作数。的行为是不确定如果右操作数 是否定的,或者大于或等于在 促进的左操作数的位长度
[...]
如果E1有一个签名的类型和负值,结果值是实现定义的。
你似乎左右混淆了。相关报价是“如果E1 有签名类型和负值,则结果值是实现定义的”(未定义)。 –
使用带符号整数进行移位是实现定义的,但是如果您使用的架构有算术移位,则可以非常可靠地使用它进行猜测。
这是因为计算机中存储了负数。它被称为二补。要切换一个二进制补码的符号,你的NOT
它的位和加1.例如,用一个8位整数00011010
(26),首先你要NOT
得到11100101
,然后你加1并得到11100110
(-26)。问题来自最重要的位被设置。如果当你移动它的时候把0放在左边,这个数字就会变成正数,但是如果它放1,那么可能的最小结果是11111111
这就是-1。这就是算术转换的工作方式,当你移动计算机时,会添加与最左边相同的位。
所以要明确,这是什么(使用8个整数,因为它更容易和大小是任意的在这种情况下)发生的事情:11111011
被转移3向右(所以011
消失),并以来最显著位被设置为3 1
s被插入在顶部,所以你得到11111111
这是-1。
这种情况是实现定义的,而不是未定义的。 –
固定。感谢您的更正。 – Tyler
由于右移复制符号位。如果从负数开始,则以负数结束(二进制中的所有数字,即2的补数为-1)。 – oakad
@oakad例如-5对于一个字节表示为1000 0101。如果我们为我们1111 0000做右移。我们如何得到-1? – venkysmarty
@venkysmarty -5在8位是11111011.右移3会给你11111111. http://en.wikipedia.org/wiki/Two%27s_complement – oakad