这是片段:
var i = 101;
console.log('101: ' + i.toString(2));
console.log('101 >> 1: ' + (i >> 1).toString(2));
var l = -101;
console.log('-101: ' + l.toString(2));
console.log('-101 >> 1: ' + (l >> 1).toString(2));'
Output:
"101: 1100101"
"101 >> 1: 110010"
"-101: -1100101"
"-101 >> 1: -110011"
Why -101 >> 1
is -110011
代替-110010
?
更新:书本面向 Web 开发人员的专业 JavaScript解释如何存储负数:
- 获取负数绝对值的二进制表示
- 将 0 替换为 1,将 1 替换为 0
- 步骤 2 的结果加 1
所以就我而言-101 >> 1
,我们首先将 -101 转换为其二进制表示形式:
-
Math.abs(-101) 的二进制表示为:
0000 0000 0000 0000 0000 0000 0110 0101
-
反转 0 和 1:
1111 1111 1111 1111 1111 1111 1001 1010
-
末尾加1:
1111 1111 1111 1111 1111 1111 1001 1011
-
现在,将其向右移动 1:
1111 1111 1111 1111 1111 1111 1100 1101
上面的二进制应该是正确的结果-101 >> 1
,但是当记录负数的二进制表示形式时,Javascript 只是在正数的二进制表示形式前面放置一个负号:
var x = 15;
console.log(x.toString(2)); // output: 1111
var y = -15;
console.log(y.toString(2)); // output: -1111
对于我们的示例,这意味着在记录结果时-101 >> 1
,JS会输出minus sign
+ the binary representation of the positive number
。但正数不是101 >> 1
因为101 >> 1
给你:
(101 >> 1).toString(2); // output: 110010
(-101 >> 1).toString(2); // output: -110011, not -110010!
为了得到正确的结果,我们必须颠倒上述步骤1-3:
1111 1111 1111 1111 1111 1111 1100 1101 // this is the result we get from step 4
将步骤 3 反转,减去 1,我们得到:
1111 1111 1111 1111 1111 1111 1100 1100
通过反转 0 和 1 来反转步骤 2:
0000 0000 0000 0000 0000 0000 0011 0011
通过将此二进制转换为整数来反转步骤 1:
parseInt(110011, 2); // output: 51
最后,当 JS 记录结果时-101 >> 1
, 这将是minus sign
+ the binary representation of 51
这是:
(51).toString(2); // output: 110011
(-101 >> 1).toString(2); // output: -110011