2014-04-29 39 views
1

我正在阅读有关C中的移位运算符。有符号数的右移运算符

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

我的问题是为什么转换有符号值可能会失败?

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

请解释一下。

+0

由于右移复制符号位。如果从负数开始,则以负数结束(二进制中的所有数字,即2的补数为-1)。 – oakad

+0

@oakad例如-5对于一个字节表示为1000 0101。如果我们为我们1111 0000做右移。我们如何得到-1? – venkysmarty

+0

@venkysmarty -5在8位是11111011.右移3会给你11111111. http://en.wikipedia.org/wiki/Two%27s_complement – oakad

回答

0

它仅仅是实现定义:

从5.8移位运算符

的操作数应为整体的或无作用域枚举类型并且执行 积分促销。结果的类型是 升级的左操作数。的行为是不确定如果右操作数 是否定的,或者大于或等于在 促进的左操作数的位长度

[...]

如果E1有一个签名的类型和负值,结果值是实现定义的。

+0

你似乎左右混淆了。相关报价是“如果E1 有签名类型和负值,则结果值是实现定义的”(未定义)。 –

-1

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

这是因为计算机中存储了负数。它被称为二补。要切换一个二进制补码的符号,你的NOT它的位和加1.例如,用一个8位整数00011010(26),首先你要NOT得到11100101,然后你加1并得到11100110(-26)。问题来自最重要的位被设置。如果当你移动它的时候把0放在左边,这个数字就会变成正数,但是如果它放1,那么可能的最小结果是11111111这就是-1。这就是算术转换的工作方式,当你移动计算机时,会添加与最左边相同的位。

所以要明确,这是什么(使用8个整数,因为它更容易和大小是任意的在这种情况下)发生的事情:11111011被转移3向右(所以011消失),并以来最显著位被设置为3 1 s被插入在顶部,所以你得到11111111这是-1。

+0

这种情况是实现定义的,而不是未定义的。 –

+0

固定。感谢您的更正。 – Tyler