~
forces the operand to get cast to an integer. It's a trick to work around the fact that Javascript has no direct way of casting between floating point and integer values. In fact, Javascript doesn't officially have an integer-only type, but implementations are likely to use integers internally for performance.
So ~x
is the bitwise inverse of castToInt(x)
. Then you inverse the bits again to get just castToInt(x)
.
It happens that casting floating point numbers to integer behaves almost like Math.floor
. The most notable difference is that casting rounds towards zero, while Math.floor
rounds towards negative infinity. There are some other differences as well:
js> ~~(-4.5)
-4
js> Math.floor(-4.5)
-5
js> ~~Infinity
0
js> Math.floor(Infinity)
Infinity
js> ~~NaN
0
js> Math.floor(NaN)
NaN
js> Math.floor(1e12)
1000000000000
js> ~~1e12
-727379968 // <- be aware of integer overflows!