为什么,在javascript中,是'2<< -1`零而不是一个?

时间:2018-04-04 18:57:16

标签: javascript bit-manipulation bitwise-operators

我遇到了按位左移运算符的这种相当奇怪的行为,我想更好地理解它......

假设我们要构建一个接收整数并返回相关整数2的函数,即:

power => Math.pow(2, power)

更有效的方法是使用shift-left按位运算符(让我们说溢出不是问题):

power => 1 << power

这很好用。奇怪的是,这也应该有效:

power => 2 << (power-1)

因为它来自:

  • 2 == 1 << 1 (按位编码为2)
  • (a << b) << c == a << (b + c) <<的语义)

然而事实并非如此,因为:

2 << -1 == 0

所以,第二定律失败了:

0 == 2 << -1 == (1 << 1) << -1 != 1 << (1 + -1) == 1 << 0 == 1

起初我认为通过负数换算是一个问题,也许js将负数解释为零?然而,事实并非如此,例如:

1 << -31 == 2

正如所料。更重要的是:

2 << 31 == 2 << -1 == 0

那么......这里发生了什么?测试2的所有班次值,所有这些值都产生预期值,除了与-1 mod 32一致的数字,即使是正数,也只产生零而不是一。

有谁知道为什么会这样?

1 个答案:

答案 0 :(得分:2)

非常简单,您只需遵循ecmascript标准定义的步骤:

Ecmascript << operator

据此,当你做2&lt;&lt; -1:

  • -1传递给unsiged int 32,表示4294967295(-1&gt;&gt;&gt; 0)
  • 仅考虑5个最低有效位:4294967295&amp; 0x1F = 31
  • 2&lt;&lt; 31给我们0