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

bro*_*oli 5 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.

有谁知道为什么会这样?

juv*_*ian 2

它非常简单,您所要做的就是遵循 ecmascript 标准定义的步骤:

Ecmascript << 运算符

据此,当你做 2 << -1 时:

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