JavaScript ES6 (<<) 中的按位左移是否在 63 位以上循环?

Are bitwise left shifts in JavaScript ES6 (<<) cyclical above a shift of 63?

我对JS(ES6)中的<<左位运算符的理解是右边的空位用0填充。

然而,根据经验,我注意到在 V8 和 JSC 中,如果我们移动 64 位或更多位,设置位似乎会突然重新出现。

(255 << 64).toString(2)
//-> "11111111" 

这与我的预期相反,我的预期是较大的移位将无限期地只在右侧产生零。

我没有立即在 << 的 EcmaScript 2016 页面中看到此行为定义 – 我是否遗漏了什么,或者对于更大的转变可能未定义该行为?

规范 (Section 12.8.3.1) 指定要屏蔽的位数:

ShiftExpression : ShiftExpression << AdditiveExpression

  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be
  3. GetValue(lref).
  4. ReturnIfAbrupt(lval).
  5. Let rref be the result of evaluating AdditiveExpression.
  6. Let rval be GetValue(rref).
  7. ReturnIfAbrupt(rval).
  8. Let lnum be ToInt32(lval).
  9. ReturnIfAbrupt(lnum).
  10. Let rnum be ToUint32(rval).
  11. ReturnIfAbrupt(rnum).
  12. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  13. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

因为 64 & 0x1F 是 0,这意味着 "no shifting",这就是为什么这些位是 "reappearing".

tl;博士

要移动的位数上限为 31,即

function shiftLeft(number, numShift) {
    return number << (numShift % 32);  // equivalent code
}