5

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

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

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

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

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

4

1 回答 1

7

规范(第 12.8.3.1 节)指定要移位的位数被屏蔽:

ShiftExpression:ShiftExpression << AdditiveExpression

  1. 令 lref 为评估 ShiftExpression 的结果。
  2. 让 lval 成为
  3. 获取值(lref)。
  4. ReturnIfAbrupt(lval)。
  5. 令 rref 为 AdditiveExpression 求值的结果。
  6. 设 rval 为 GetValue(rref)。
  7. ReturnIfAbrupt(rval)。
  8. 令 lnum 为 ToInt32(lval)。
  9. ReturnIfAbrupt(lnum)。
  10. 设 rnum 为 ToUint32(rval)。
  11. ReturnIfAbrupt(rnum)。
  12. 令 shiftCount 为屏蔽掉除 rnum 的最低有效 5 位以外的所有结果,即计算 rnum & 0x1F。
  13. 通过 shiftCount 位返回 lnum 左移的结果。结果是一个有符号的 32 位整数。

由于 64 & 0x1F 为 0,这意味着“没有移位”,这就是位“重新出现”的原因。

tl;博士

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

function shiftLeft(number, numShift) {
    return number << (numShift % 32);  // equivalent code
}
于 2018-08-22T21:20:04.237 回答