8
    -5 / 2 = -2

    -5 >> 1 = -3

我从老师那里了解到 >>1 将数字除以 2。它适用于正数,但不适用于负数。谁能给我解释一下??

谢谢

4

7 回答 7

6

正如 BЈовић & 神秘状态,对负数使用位移运算符是实现定义的。
原因是 C 不区分逻辑位移和算术位移。
(具有最高有效位的算术填充,带 0 的逻辑填充)
对于正数这无关紧要,因为算术和逻辑位移都会将最高有效位保持为 0:
算术 5>>1
0000 0000 0000 0101 = 5

0000 0000 0000 0010 = 2

逻辑 5>>1
0000 0000 0000 0101 = 5

0000 0000 0000 0010 = 2

但是使用负数(2 的补偿)
算术 -5>>1
1111 1111 1111 1011 = -5

1111 1111 1111 1101 = -3

逻辑 -5>>1
1111 1111 1111 1011 = -5

0111 1111 1111 1101 = 32,765

或者至少,我是这样理解的

于 2012-12-13T11:38:32.837 回答
5

它适用于正数,但不适用于负数。

对负整数使用移位运算符是实现定义的。


[expr.shift]/3 告诉这个:

E1 >> E2 的值是 E1 右移 E2 位位置。如果 E1 具有无符号类型或 E1 具有带符号类型和非负值,则结果的值是 E1/2E2 的商的整数部分。如果 E1 具有带符号类型和负值,则结果值是实现定义的。

于 2012-12-13T11:17:06.297 回答
1

首先,
二进制中的 5 是 0000 0000 0000 0101 但是 -5 呢?这里是 :

  1. 将 1 更改为 0 并将 0 更改为 1 ,然后我们得到 1111 1111 1111 1010
  2. 然后取那个数字 + 1 ,我们得到 1111 1111 1111 1011

现在我们得到: -5= 1111 1111 1111 1011 (它是 2 的补码形式)
所以这里是如何计算 -5>>1 :

  1. 将 -5 的每一位从左向右移动 ( >> ) 我们得到111 1111 1111 1101 (只剩下 15 位)
  2. 因为-5是负数,所以我们必须在第一位填充'1'使其变为16位然后我们得到1111 1111 1111 1101(它仍然是2的补码形式)
  3. 现在通过将 0 更改为 1 ,将 1 更改为 0 将其转换为正常的二进制形式(除了第一位,因为它在 2 的补码中定义负数),然后加上 '1' 。所以我们得到 1000 0000 0000 0011 = -3
于 2013-03-18T16:22:35.040 回答
1

我从老师那里得知 >>1 将数字除以 2。

它不会将整数除以 2,但会执行(取决于值)逻辑算术右移一位。在某些情况下,它恰好等于除以二。

它适用于正数,但不适用于负数。

它适用于这两种情况,但确切的行为不是标准规定的,而是实现定义的。它通常除以 2 并将结果截断为负无穷大,与正常除法的结果相反,趋向于零。

以供参考:

于 2012-12-13T12:42:11.410 回答
0

我猜是-5>>1 = -3的答案。如果是正数,比如 5,除以 2 会得到 2.5 四舍五入到最接近的最小整数,即 2

但是当我们考虑负数 -5 时,除以 2 得到 -2.5。它四舍五入到最接近的整数给出-3。

于 2013-08-05T10:41:31.147 回答
0

在c中,右移运算符保留符号位。因此,在保留符号位的情况下右移位再次产生一个负数,它是两个补码形式。

于 2013-09-20T22:32:04.410 回答
0

我认为答案是正确的。作为'/'(除法)运算符生成商(除法的结果)。

在您的问题中:

-5/2 = -3(quotient) and 1(remainder ). 

所以这对正数和负数都可以。

正数:

5/2 = 2(quotient) and 1(remainder ). 

所以用正数就可以了。

笔记

余数永远不会是负数。它始终是正数。

于 2012-12-13T11:31:37.097 回答