【问题标题】:Why does << 32 not result in 0 in javascript?为什么 << 32 在javascript中不会导致 0?
【发布时间】:2014-08-08 21:36:14
【问题描述】:

这是错误的:

(0xffffffff << 31 << 1) === (0xffffffff << 32)

看起来应该是真的。在任何地方添加&gt;&gt;&gt; 0 不会改变这一点。

为什么会这样?如何正确编写处理 &lt;&lt; 32 的代码?

【问题讨论】:

  • 你想做什么?为什么?每个操作数的值是多少?
  • EcmaScript 5。注意第 7 步。
  • 我在一个用于管理网络掩码的 node.js 模块中遇到了这个问题。它做了一个

标签: javascript bit-manipulation unsigned bit-shift integer-overflow


【解决方案1】:

移位运算符总是有效地在 0-31 范围内有一个右操作数。

来自the Mozilla docs

移位运算符以大端顺序将其操作数转换为 32 位整数,并返回与左操作数相同类型的结果。右操作数应小于 32,但如果不只使用低五位

或来自ECMAscript 5 standard

产生式 ShiftExpression : ShiftExpression

  1. lref 为计算 ShiftExpression 的结果。
  2. lval 为 GetValue(lref)。
  3. rref 成为评估 AdditiveExpression 的结果。
  4. rval 为 GetValue(rref)。
  5. lnum 为 ToInt32(lval)。
  6. rnum 为 ToUint32(rval)。
  7. 令 *shiftCount 为屏蔽掉 > rnum 的最低有效 5 位以外的所有结果,即计算 rnum & 0x1F。
  8. 返回将 lnum 左移 shiftCount 位的结果。结果是一个带符号的 32 位整数。

(对于其他移位运算符也是如此。)

我并不完全清楚为什么会出现这种情况,但 Java 和 C# 的 32 位整数类型的工作方式相同。 (对于 64 位整数类型,操作数在 0-63 范围内。)例如,参见 JLS 15.19

我的猜测是这在通用处理器平台上是有效的,但我没有证据证明...

【讨论】:

  • 看起来确实很奇怪。如果它是一个位旋转,那么它是有道理的,但是对于位移......?
  • @NiettheDarkAbsol:我怀疑这是为了提高效率。
  • @NiettheDarkAbsol 大多数 JS 引擎都广泛优化了 SMI。 V8 就是一个很好的例子。
  • @JLRishe 0xffffffff &lt;&lt; 31 == 0x80000000,而 0xffffffff &lt;&lt; 32 == 0xffffffff - 这些显然不相等 ;)
  • @Killroy:是的,这是合乎逻辑的。但这不是定义语言的方式,正如我的回答所示。
猜你喜欢
  • 2012-01-30
  • 2012-12-31
  • 2019-05-06
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多