我在Javascript中注意到的一件事-
& lt; & lt;1
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将操作数和移位值视为位序列而不是数字。它适用于32位整数(浮点数被截断),最大位移为32位。如果我们移动一个大于32的数,所有的位都会移出,结果是0。为了确保移位小于或等于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 >>> 1 = 7
的答案。
Javascript总是处理32位。所以当我做-2 >>> 1
时,真正发生的是11111111111111111111111111111110 >>> 1
得到01111111111111111111111111111111 = (2147483647)base10
LeftShift运算符在数字的二进制表示右边加零,将位移到左边。只使用加法表达式的最低五位有效数字。所以:
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,因为shift只使用加法表达式的最后5位,即1000000,因此只使用00000部分。