为什么 Ruby 和 JavaScript 位运算符使用相同的操作数会产生不同的结果?
例如:
256 >> -4 # => 4096 (Ruby)
256 >> -4 # => 0 (Javascript)
任何提示/指针表示赞赏。
为什么 Ruby 和 JavaScript 位运算符使用相同的操作数会产生不同的结果?
例如:
256 >> -4 # => 4096 (Ruby)
256 >> -4 # => 0 (Javascript)
任何提示/指针表示赞赏。
对于 Ruby 版本,它看起来256 >> -4
等价于256 << 4
,因此负操作数本质上只是切换移位的方向。
通过查看右移运算符的 ECMAScript 规范,在 JavaScript 中,操作数在移位之前被转换为无符号 32 位整数,因此-4
变成4294967292
. 在此转换之后,5 个最低有效位用于移位,换句话说,我们最终将按位移4294967292 & 0x1f
位(结果为28
)。看到256 >> 28
给0
.
为方便起见,以下是规范中的文本(步骤 6 和 7 与您的困惑最相关):
有符号右移运算符 (
>>
)按右操作数指定的量对左操作数执行符号填充按位右移操作。
产生式 ShiftExpression : ShiftExpression >> AdditiveExpression的评估如下:
- 让
lref
是评估ShiftExpression的结果。- 让。
lval
_GetValue(lref)
- 让
rref
是评估AdditiveExpression的结果。- 让。
rval
_GetValue(rref)
- 让。
lnum
_ToInt32(lval)
- 让。
rnum
_ToUint32(rval)
- 让
shiftCount
成为屏蔽除 的最低有效 5 位(rnum
即计算 )之外的所有结果的结果rnum & 0x1F
。- 返回执行符号扩展右移一位的
lnum
结果shiftCount
。传播最高有效位。结果是一个有符号的 32 位整数。
附带说明一下,如果您想通过将值转换为无符号 32 位整数来解决此问题,您可以使用V8 JavaScript 引擎中的touint32.jsval >>> 0
中所见。