两者在MDN上的右移运算符示例:
对我来说毫无意义。他们不仅挑战了我对两个补数的理解,而且使我对自己的功能产生了困惑。我是否缺少某些内容,或者这些示例需要更正吗?
下面给出了一些令人困惑的示例,其中包含对我的期望的评论。
右移运算符的负数示例如下:
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
这是怎么回事?
带有负数的示例显示为:
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
我认为这只是一个印刷错误?
答案 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
,负数为0
和1
。
-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 >> 2
是111...11111110
,它是-2
的二进制表示形式。
unsigned right shift operator (>>>
)(也称为“零填充右移”和"logical right shift")也将位向右移位并丢弃最右边的位,但是它始终使用0
来填充左侧的释放位置。
-5 >>> 2
是00111...11111110
,它是正数1073741822
(=2^30-2
)