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
- Let lref be the result of evaluating ShiftExpression.
- Let lval be
- GetValue(lref).
- ReturnIfAbrupt(lval).
- Let rref be the result of evaluating AdditiveExpression.
- Let rval be GetValue(rref).
- ReturnIfAbrupt(rval).
- Let lnum be ToInt32(lval).
- ReturnIfAbrupt(lnum).
- Let rnum be ToUint32(rval).
- ReturnIfAbrupt(rnum).
- Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
- 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
}
我对JS(ES6)中的<<左位运算符的理解是右边的空位用0填充。
然而,根据经验,我注意到在 V8 和 JSC 中,如果我们移动 64 位或更多位,设置位似乎会突然重新出现。
(255 << 64).toString(2)
//-> "11111111"
这与我的预期相反,我的预期是较大的移位将无限期地只在右侧产生零。
我没有立即在 << 的 EcmaScript 2016 页面中看到此行为定义 – 我是否遗漏了什么,或者对于更大的转变可能未定义该行为?
规范 (Section 12.8.3.1) 指定要屏蔽的位数:
ShiftExpression : ShiftExpression << AdditiveExpression
- Let lref be the result of evaluating ShiftExpression.
- Let lval be
- GetValue(lref).
- ReturnIfAbrupt(lval).
- Let rref be the result of evaluating AdditiveExpression.
- Let rval be GetValue(rref).
- ReturnIfAbrupt(rval).
- Let lnum be ToInt32(lval).
- ReturnIfAbrupt(lnum).
- Let rnum be ToUint32(rval).
- ReturnIfAbrupt(rnum).
- Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
- 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
}