JavaScript ES6(<<)中的按位左移是否在63的移位之上是周期性的?

时间:2018-08-22 21:10:06

标签: javascript v8 javascriptcore

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

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

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

这与我的预期相反,因为较大的偏移会无限期地在右侧无限地产生零。

在EcmaScript 2016页面的<<上,我没有立即看到这种行为–是我遗漏了什么,还是对于较大的班次可能未定义这种行为?

1 个答案:

答案 0 :(得分:7)

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

  

ShiftExpression:ShiftExpression << AdditiveExpression

     
      
  1. 让lref成为评估ShiftExpression的结果。
  2.   
  3. 让lval成为
  4.   
  5. GetValue(lref)。
  6.   
  7. ReturnIfAbrupt(lval)。
  8.   
  9. 让rref成为评估AdditiveExpression的结果。
  10.   
  11. 让rval为GetValue(rref)。
  12.   
  13. ReturnIfAbrupt(rval)。
  14.   
  15. 让lnum为ToInt32(lval)。
  16.   
  17. ReturnIfAbrupt(lnum)。
  18.   
  19. 让rnum为ToUint32(rval)。
  20.   
  21. ReturnIfAbrupt(rnum)。
  22.   
  23. 让shiftCount是屏蔽掉rnum的除最低有效5位以外的所有位的结果,即计算rnum&0x1F。
  24.   
  25. 通过shiftCount位返回左移lnum的结果。结果是一个有符号的32位整数。
  26.   

由于64&0x1F为0,表示“无移位”,这就是为什么这些位“重新出现”的原因。

tl; dr

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

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