哈克将javascript编号转换为UInt32

时间:2014-03-11 20:24:24

标签: javascript bit-manipulation operator-keyword indexof uint32

修改:由于Polyfill示例已更新,此问题已过期。我在这里留下这个问题仅供参考。请阅读正确答案,了解有关按位移位运算符的有用信息。


问题:

在Mozilla Array.prototype.indexOf页面的Polyfill示例的第7行,他们对此进行评论:

var length = this.length >>> 0; // Hack to convert object.length to a UInt32

但Mozilla上的bitwise shift规范明确指出运算符返回与左操作数相同类型的值:

  

移位运算符将其操作数转换为32位整数,并返回与左操作数相同类型的结果。

那么长度是否应该接收标准的64位浮点值?或者有人能指出我黑客入手的地方?

3 个答案:

答案 0 :(得分:8)

ECMAScript规范声明该值在http://www.ecma-international.org/ecma-262/5.1/#sec-11.7的步骤5和8中转换为UInt32:

  

11.7.3无符号右移运算符(>>>)

     

对左操作数执行零填充按位右移操作,其数量为>由右操作数指定。

     

生产ShiftExpression : ShiftExpression >>> AdditiveExpression的评估如下:

     
      
  1. lref成为评估ShiftExpression
  2. 的结果   
  3. lval成为GetValue(lref)
  4.   
  5. rref成为评估AdditiveExpression
  6. 的结果   
  7. rval成为GetValue(rref)
  8.   
  9. lnumToUint32(lval)
  10.   
  11. rnum成为ToUint32(rval)
  12.   
  13. shiftCount成为屏蔽除rnum的最低5位之外的所有内容的结果,即计算rnum & 0x1F
  14.   
  15. 返回lnumshiftCount执行零填充右移的结果。空位用零填充。 结果是无符号的32位整数
  16.   

答案 1 :(得分:2)

实际上,结果被转换回数字,即64位精度浮点数。但是,在转换回来之前,两个操作数都转换为UInt32,然后执行右移操作。这在ECMAScript中指定: http://www.ecma-international.org/ecma-262/5.1/#sec-11.7.3

length >>> 0的最终结果因为>>> 0本身是无操作,将length转换为UInt32然后转换为双倍。到底有什么好处呢?它会强制精度损失,并有效地强制值为1),整数和2)在[0,2 ^ 32-1]范围内。例如,如果它是-1,它将变为2 ^ 32-1 == 4294967295。如果是3.6,它将变为3。

答案 2 :(得分:0)

如果您运行此测试,Math.floor也会这样做。如果您想在一个月左右的时间内了解自己的代码,就应该避免这些黑客攻击。

var a=3.6, b = a >>> 0;
console.log(b);
console.log(Math.floor(a));