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

Why, in javascript, is `2 << -1` zero instead of one?

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

假设我们要构建一个接收整数和 return 相关联的二的整数幂的函数,即:

power => Math.pow(2, power)

一种更有效的方法是使用左移按位运算符(假设溢出不是问题):

power => 1 << power

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

power => 2 << (power-1)

因为它来自:

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

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 一致的数字外,所有这些值都产生预期值,即使是正值,它们产生零而不是一。

有人知道为什么会这样吗?

非常简单,您只需按照 ecmascript 标准定义的步骤操作即可:

Ecmascript << operator

据此,当你执行 2 << -1:

  • -1 传递给 unsiged int 32,即 4294967295 (-1 >>> 0)
  • 仅考虑 5 个最低有效位:4294967295 & 0x1F = 31
  • 2 << 31 给我们 0