【问题标题】:Left shifting with a negative shift count in Javascript在 Javascript 中以负移位计数左移
【发布时间】:2013-05-15 08:12:04
【问题描述】:
我在 Javascript 中注意到的一件事 -
一个
Returns 0 when a = even.
Returns -2147483648 when a = odd.
同样,当-1 更改为其他-ve 数字时,会返回不同的值。
有人能解释一下幕后发生了什么位操作吗?还是行为未定义?
谢谢
编辑
也不应该零填充右移,即-2 >>> 1返回7?
-2 = 1110。之后,用零填充右移,它应该给出 0111 = 7
但是
a = -2; console.log(a >>> 1);
返回
2147483647
【问题讨论】:
标签:
javascript
bitwise-operators
【解决方案1】:
我也很想知道这就是我来到这里的原因。我做了一些研究并弄清楚了这种行为。本质上 JavaScript 将操作数和移位值视为位序列而不是数字。它适用于 32 位整数(浮点数被截断),最大移位为 32 位。如果我们移动一个大于 32 的数字,所有位都会移出,结果为零。为了确保移位小于或等于 32,JavaScript 会截断 5 个最低有效位 [a << (b&0x1F)] 或可能使用模数方法 [a << (b%32)] 来产生相同的结果。
除此之外,将要移位的负数视为位序列,而不是负数(即-1)。在这种情况下b = -1 = 0xFFFFFFFF。由于此数字大于 32,因此将其截断为0xFFFFFFFF & 0x1F = 31 或0xFFFFFFFF % 32 = 31。
因此,在您的示例中,“a”从最低有效位一直移动到最高有效位(符号位)。因此,移位的结果是 0x00000000 或 (0x80000000 = -2147483648),具体取决于操作数是否设置了 1 位(奇数或偶数)。
【解决方案2】:
得到我问题第二部分的答案,即-2 >>> 1 = 7。
Javascript 总是处理 32 位。所以当我做-2 >>> 1 时,真正发生在幕后的是——
11111111111111111111111111111110 >>> 1 给出01111111111111111111111111111111 = (2147483647)base10
【解决方案3】:
LeftShift 运算符在数字的二进制表示的右侧添加零,将位向左移动。仅使用加法表达式的 5 个最低有效数字。所以:
var x = 5 // 101
alert( x << 1 ); // 1010 = 10
alert( x << 2 ); // 10100 = 20
alert( x << 3 ); // 101000 = 40
alert( x << 4 ); // 1010000 = 80
alert( x << 64 ); // 101 = 5
最后一个表达式返回 5,因为移位仅使用加法表达式的最后 5 位,即 1000000,因此仅使用 00000 部分。