"x|0" is the preferred idiom for this IMHO; it's one character cheaper than the shift and calls [[ToInt32]] in the same way. IIRC this is what Emscripten uses.
Good thing to keep in mind is that Math.floor(-1.1) is -2, whereas -1.1|0 is -1. There is also an issue with x|0 in that you can't use it with values greater than 2^32 (or Math.pow(2, 32)) as those always return a 0 (you get this same issue with the bitwise operation) whereas those values work with Math.floor
That's not exactly true; what x|0 essentially does, like x<<0, ~~x and x>>0, is cast x to a signed 32-bit integer, which truncates the fractional part and causes wrap-around for values outside of -2147483648..2147483647. (Math.pow(2,32)+1)|0 is 1.
A good thing to keep in mind is the behavior at the extremities. If you look at negative numbers (Math.floor(-1.1) == -2, whereas parseInt("-1.1", 10) == -1, and -1.1 << 0 == -1) and numbers greater than 2^32 (Math.floor and parseInt work for those values, but bitwise shifting always returns 0) the behavior is different.
Math.floor is the right choice 99% of the time for three reasons:
1. it will always behave correctly (barring implementation bugs)
2. readable/mantainable code comes first
3. leave tricks to the interpreter
4. you're not gonna do 60 million flooring ops/s
5. -1.1 is really -2+.9
The author missed the ~~1.1 trick (essentially the same as << 0).
But for practical reasons I'll stick with Math.floor. It makes my code more readable. Plus, Chrome is already faster using Math.floor. I'm sure the other browsers will catch up, or I at least hope they will.
Agreed. I don't think I've ever come anywhere near an application which was significantly slowed down because it did too many float-to-int conversions. Thankfully, JSLint will complain about people using the bitshift operators in practice.
Actually, that's a bit of a lie: when I wrote SHA3 candidates in JS, they were bitwise-operation-heavy and they probably did have slow [ToInt32] calls in the middle of performance-critical loops. But you see my point: I've never seen or written code whose performance would be significantly impacted by writing x | 0 in place of Math.floor(x). Maybe the number of keystrokes is saved, that might be a good argument, but the performance?
A slight variation along the same lines is x >>> 0, which differs in that it yields positive values for values between 2^31 and 2^32-1 inclusive, effectively acting as a C cast to uint32_t instead of int32_t. It runs in roughly the same time as the other bitwise truncation idioms on Firefox 15 alpha, with Math.floor being slightly faster than them.
I am impressed. I thought you were surely wrong, then I checked it in Firebug, then I checked it in the ECMA-262 standard, and yes, a >>> b is indeed a uint32 operator.