Donnerstag, 11. Februar 2010

The Bitwise Not Operator aka. ~

I often have seen code like this:

Array.prototype.inArray = function(arg){
return !!~this.indexOf(arg);
};

Let's assume this piece of code would be C++. this.indexOf(arg) would then return an integer which is the index of arg if arg is in the array, else it will return -1; Since most CPUs use the two's complement the -1 would be represented by 0xFF. All the other indices will be simple binary numbers. The ~ operator flips all bits. So -1 will then be 0x00 where as the other numbers will become something else. The first ! turns the 0x00 into a true and the rest into a false. The last ! swaps that again. So we started with a -1 end ended with a false. A 3 would be converted to true. The sole reason C++ programmers use the ~ instead of >= 0 is to save a few nanoseconds. Flipping bits is slightly faster than a comparison.

But this is not C++ its JS. JS has no integer values. All numbers are of the type best known as double. But that is a difficult standard and since JS was supposed to be easy ~ does not flip the bits in the 64-Bit floating point representation. Instead the number is converted to a 32-bit signed integer in two's complement. Than the bits are inverted. Afterwards it gets converted backwards.


You see that the ~ operator does things slower than expected. Do not use it. It only makes you look rather stupid.


mfG Kambfhase

1 Kommentar:

  1. I was interested in seeing if there really is a performance difference between ~~ and Math.floor() (for positive integers). In my googling, I came by this jsperf: http://jsperf.com/rounding-numbers-down

    The results there indicate that the performance hit you worry about really doesn't exist and the bitwise operators are the faster options.

    AntwortenLöschen