这些右移运算符示例正确吗?

时间:2018-06-28 07:24:04

标签: javascript

两者在MDN上的右移运算符示例:

  1. 右移运算符;和
  2. 无符号右移运算符

对我来说毫无意义。他们不仅挑战了我对两个补数的理解,而且使我对自己的功能产生了困惑。我是否缺少某些内容,或者这些示例需要更正吗?

下面给出了一些令人困惑的示例,其中包含对我的期望的评论。

  1. Right-shift operator

    右移运算符的负数示例如下:

    var bar -5; // (-00000000000000000000000000000101)

    bar >>= 2; // -2 (-00000000000000000000000000000010)

    首先,假设DWORD大小(32位,带符号),-5的二进制补码表示为11111111111111111111111111111011。而且我什至不知道上面示例中提供的表示形式(-00000000000000000000000000000101)意味着什么。

    第二,如果我仅通过阅读示例来推断其含义,它可能是在说:

    采用第一个操作数的正表示,将第二个操作数的位数向右移动,将其转换为小数,然后将任何符号(正或负)重新应用于结果。 / em>

    但是,我也尝试过,按照这种解释,结果应该是-1而不是-2,如下所示。

    var bar -5; // (-00000000000000000000000000000101)

    bar >>= 2; // -1 (-00000000000000000000000000000001)

    因此,为了测试该示例,我键入了以下JavaScript代码,然后瞧!它确实产生了所记录示例的目的。

    console.log(5 >> 2) // produces -2

    这是怎么回事?

  2. Unsigned Right-Shift Operator

    带有负数的示例显示为:

    var bar = -5; // (-00000000000000000000000000000101)

    bar >>>= 2; // 1073741822 (00111111111111111111111111111110)

    有了这个,我唯一的抱怨是-5的二进制表示是错误的。如果已纠正,则该示例完全有意义。正确的示例如下:

    var bar = -5; // (11111111111111111111111111111011)

    bar >>>= 2; // 1073741822 (00111111111111111111111111111110)

    如上所述,11111111111111111111111111111011右移两个位将产生00111111111111111111111111111110,这将产生正数1073741822

    我尝试过,它会产生正确的结果:

    console.log(5 >>> 2); // produces 1073741822

    我认为这只是一个印刷错误?

2 个答案:

答案 0 :(得分:1)

1)忽略二进制表示形式,因为它不是很有用。它实际上是带符号的二进制表示形式,实际上并不存在于计算机中,因为计算机将带符号的数字表示为二进制补码,而不是带符号的二进制表示。

如您所说,

-5表示为...11111011~4)。将其右移两次,同时复制MSB以保留符号,您将得到...11111110的表示形式的~1-2)。

2)同样,-5的二进制表示形式是正确,但不是有用的,因为这不是计算机使用的表示形式 。对于人类数学,+5(10)+101(2)相同,-5(10)-101(2)相同;但是计算机分别将它们表示为...00000101...11111011

答案 1 :(得分:1)

MDN提供的示例令人困惑,因为它们没有显示负数的真实二进制表示形式。

-5的二进制表示形式为111...11111011(用1填充省略号以达到32位的总长度)。

>>

常规right shift operator (>>)(也称为“符号传播移位”和"arithmetic shift")将这些位向右移位,丢弃最右边的位,并使用最左边的位来填充新的释放左侧的职位。

在二进制补码二进制表示形式中(当今大多数计算机都在使用),最左边的位是符号位。正数为0,负数为01

-5的二进制补码二进制表示为:

+---+---+---+---+---+----------+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | ........ | 1 | 1 | 0 | 1 | 1 |
+---+---+---+---+---+----------+---+---+---+---+---+
|                                          |       |
   \------------------------------------/    ^   ^
  ^     these bits moves to the right        +---+------ these 2 bits are discarded
  |
  +---- the value of this bit is used to fill the 2 leftmost freed positions

-5 >> 2111...11111110,它是-2的二进制表示形式。

>>>

unsigned right shift operator (>>>)(也称为“零填充右移”和"logical right shift")也将位向右移位并丢弃最右边的位,但是它始终使用0来填充左侧的释放位置。

-5 >>> 200111...11111110,它是正数1073741822=2^30-2