Mehdi Luthon's blog back to main page

Double bitwise NOT in javascript.

As you probably know double bitwise NOT operator can be used to convert a value of type string representing a number "1" to a value of type number 1.
The operation is faster and the notation is shorter but less readable than with parseInt() or parseFloat() which is the usual way to perform such a conversion, another caveat is that the string representing a number must be in the range of a 32-bit integer thus from -2147483648 to 2147483647, also any decimal part will be lost.

But the question I was asking myself is, how it works? Let's find out by digging the official ecmascript documentation.

bitwise not javascript

Before performing any bit flipping of the value wich the bitwise NOT operator is applied to it will check if the value is a 32-bit integer, if not it converts the value to a 32-bit integer following these steps:

bitwise not javascript

If the value is not a javascript number(float64) it will follow the step one and convert it to a javascript number following these specification:

bitwise not javascript

So for what concerns us we should look at toNumber for string wich say.

bitwise not javascript

The value of the string must comply with the specification of a StringNumericLiteral otherwise ToNumber will return NaN.

Step two if number is NaN, +0, -0, +∞, or -∞, it return +0.

Step three of ToInt32 any decimal part will be truncated like with floor(abs(number)).

Step four apply a modulo operation of 2^32 to the value because the value must fit in a 32-bit integer.

bitwise not javascript

Step five ToInt32 return a signed 32-bit integer thus if the value is superior or equal to 2^31 it will return a negative number (our value - 2^32).

Now our value is properly converted to an 32-bit integer so the bit are flipped, therefore if our initial value is "0": ~"0" === -1, then ~-1 === 0. [1]

The bitwise NOT operator return a 32int that is stored as a float64 since numbers in javascript are of type float64.

This is all for today I hope it can satisfy you as much as it satisfied myself, see you.

Notes:

  • 32-bit integer have 2^31 positive value including 0, thus it can represent integers from 0 until 2147483647 (2^31 - 1) and there is 2^31 negative value from -1 until -2147483648.
    The minimum negative value is -1 represented in binary as 1111 1111 1111 1111 1111 1111 1111 1111.
    The minimum positive value is 0 represented in binary as 0000 0000 0000 0000 0000 0000 0000 0000.
    Thus after flipping all the bit ~0 === -1.

Resources:

Archives: