Javascript integers and bitwise operations

This is the first post in a series to demystify Javascript.

Javascript is the most misunderstood language, it has a huge stigma attached to it. Programmers learn it by copy-pasting it from Stack Overflow question and retroactively applying their knowledge of other languages to Javascript, but JavaScript is different. It should be treated as a mostly functional language, not as a broken Java or C# web clone and it should be learned properly. That stigma is starting to go, mostly due to projects like Node.JS, Express, EmberJS and the other client-side frameworks.

In JS, variables are declared using the var keyword. The type is inferred from the value of the variable. While JS only has a Number object to represent numbers, internally, modern engines have 2 types: 32-bit signed integers and 64-bit double-precision floats. JS switches from one type to the other automatically.

Bitwise operations is one of those cases, for obvious reasons. The AND (&), OR (|) and XOR (^) operators are well known, but the NOT (~) and bitshift operators (<<, >> and >>>) have a few less known uses. I’m going to be using 16-bit ints for my examples.


The NOT operator (~)
It flips every bit of the number. Javascript uses the Two’s complement method, so the apparent result is -(N+1). For example,

~125 //00000000 01111101

returns

-126 //11111111 10000010

It’s reversible, so ~-126 is 125 again.

Okay, I know, this isn’t very interesting nor useful. But there’s actually a neat use for it.
It parses strings! When used on non number variables, it assumes that they are 0 and thus returns -1. By using 2 tildes, they cancel each other but keep that string parsing ability.

~~"123"  //returns 123
~~123 //returns 123
~~"this is a string" // returns 0
~~{"name" : "Bob", "ID" : 789} //returns 0

And so on. It is safer and more convenient than using parseInt() because the result is assured to be a number, unlike parseInt().

Bitshifting (<<, >> and >>>)

125 << 2 //00000000 01111101

returns

500 //00000001 11110100

As you can see, it added 2 zeroes to the right of the number and the 2 left-most bits "fell off" the number and were lost.

The >> and >>> symbols are the opposite of <<.

125 >> 2 //00000000 01111101

returns

31 //00000000 00011111

>>> returns a different result than >> on negative numbers only.

-126 >> 2 //11111111 10000010

returns

-32 //11111111 11100000

As you can see, >> adds zeroes from the left to a positive number, but ones to a negative number; it's sign-aware. >>> isn't, it always adds zeroes.

-126 >>> 2 //11111111 10000010

returns

16352 //00111111 11100000

>>> always turns a negative number into a positive one, even for >>> 0.

-126 >> 0 //returns -126
-126 >>> 0 //returns 65410

That's right! The Google Chrome V8 engine (and thus Node.js) can handle unsigned integers that way. The engine will always try to go back to signed integers, but it can be useful in some cases nonetheless.

Finally, I can't mention bitshifting without making a reference to this awesome Stack Overflow question. It makes the code less readable, but it's still a good way to remove ifs in tight loops when performance is necessary... and it's a fascinating topic.

Leave a Reply