Thursday, April 19, 2012

What good does zero-fill bit-shifting by 0 do? (a >>> 0)


I just came across this piece in the Mozilla Javascript documentation:




var len = this.length >>> 0;



I don't quite understand why this is being done. What good does zero-fill right shifting this.length by 0 do? As far as I understand, it does exactly nothing. Is it to safely establish a default value for len , even if this.length is not an integer? Can this ever feasibly be the case? If so, what's the difference between >> 0 and >>> 0 ?


Source: Tips4all

3 comments:

  1. The unsigned right shift operator is used in the all the array extra's method implementations of Mozilla, to ensure that the length property is a unsigned 32-bit integer.

    The length property of array objects is described in the specification as:


    Every Array object has a length property whose value is always a nonnegative integer less than 232.


    This operator is the shortest way to achieve it, internally array methods use the ToUint32 operation, but that method is not accessible and exist on the specification for implementation purposes.

    The Mozilla array extras implementations try to be ECMAScript 5 compliant, look at the description of the Array.prototype.indexOf method (§ 15.4.4.14):


    1. Let O be the result of calling ToObject passing the this value
    as the argument.
    2. Let lenValue be the result of calling the [[Get]] internal method of O with
    the argument "length".
    3. Let len be ToUint32(lenValue).
    ....


    As you can see, they just want to reproduce the behavior of the ToUint32 method to comply with the ES5 spec on an ES3 implementation, and as I said before, the unsigned right shift operator is the easiest way.

    ReplyDelete
  2. Two reasons:


    The result of >>> is an "integral"
    undefined >>> 0 = 0 (since JS will try and coerce the LFS to numeric context, this will work for "foo" >>> 0, etc. as well)


    Remember that numbers in JS have an internal-representation of double.
    It's just a "quick" way of basic input sanity for length.

    However, -1 >>> 0 (oops, likely not a desired length!)

    ReplyDelete
  3. >>> is the unsigned right shift operator (see p. 76 of the JavaScript 1.5 specification), as opposed to the >>, the signed right shift operator.

    >>> changes the results of shifting negative numbers because it does not preserve the sign bit when shifting. The consequences of this is can be understood by example, from an interpretter:

    $ 1 >> 0
    1
    $ 0 >> 0
    0
    $ -1 >> 0
    -1
    $ 1 >>> 0
    1
    $ 0 >>> 0
    0
    $ -1 >>> 0
    4294967295
    $(-1 >>> 0).toString(16)
    "ffffffff"
    $ "cabbage" >>> 0
    0


    So what is probably intended to be done here is to get the length, or 0 if the length is undefined or not an integer, as per the "cabbage" example above. I think in this case it is safe to assume that this.length will never be < 0. Nevertheless, I would argue that this example is a nasty hack, for two reasons:


    The behavior of <<< when using negative numbers, a side-effect probably not intended (or likely to occur) in the example above.
    The intention of the code is not obvious, as the existence of this question verifies.


    Best practice is probably to use something more readable unless performance is absolutely critical:

    isNaN(parseInt(foo)) ? 0 : parseInt(foo)

    ReplyDelete