Hack to convert javascript number to UInt32

久未见 提交于 2019-12-03 12:18:46

The ECMAScript specification states that the value is converted to UInt32 in step 5 and 8 of http://www.ecma-international.org/ecma-262/5.1/#sec-11.7:

11.7.3 The Unsigned Right Shift Operator ( >>> )

Performs a zero-filling bitwise right shift operation on the left operand by the amount > specified by the right operand.

The production ShiftExpression : ShiftExpression >>> AdditiveExpression is evaluated as follows:

  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating AdditiveExpression.
  4. Let rval be GetValue(rref).
  5. Let lnum be ToUint32(lval).
  6. Let rnum be ToUint32(rval).
  7. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  8. Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.

The result is, indeed, converted back to a number, i.e., a 64-bit precision floating point number. However, before it is converted back, both operands are converted to UInt32, then the right shift operation is performed. This is specified in ECMAScript here: http://www.ecma-international.org/ecma-262/5.1/#sec-11.7.3

The net result of length >>> 0 is therefore, because >>> 0 itself is a no-op, to convert length to a UInt32 then back to a double. What is it good for? It forces the loss of precision, and effectively forces the value to be 1) and integer and 2) in the range [0, 2^32-1]. For example, if it was -1, it will become 2^32-1 == 4294967295. If it was, 3.6, it will become 3.

If you run this test, Math.floor will do the same. Those hacks should be avoided if you want to understand your own code in a month or so.

var a=3.6, b = a >>> 0;
console.log(b);
console.log(Math.floor(a));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!