logo

NJP

JavaScript: Bitwise Operators - &, |, and ~...

Import · Mar 29, 2011 · article

imageRecently I was talking with a customer I'll call Paula who needed to set one particular bit in a numeric variable, to call a Java class that used a "flags" parameter. In this particular case, she needed to set bit 3, which is the bit with a value of 23, or 8. The variable that held the flags might or might not have bit 3 already set. She didn't know about JavaScript's bitwise operators, which make this kind of thing very easy. Instead, she was trying to do it with operators like add ('+') and subtract ('-'), and that wasn't working out all that well.

So how could she have done this, easily?

JavaScript's bitwise operators perform logical operations on the binary value of the operands, which (oddly for JavaScript) are treated as 32 bit integers (not the usual double floating-point value). Paula could have used the logical OR operator ('|') to solve her problem, as in this code:

flags = flags | 8;

flags |= 8; // exactly the same result, more concisely...

For instance, imagine that her 'flags' variable contained the value 131. Here's what that math looks like, in decimal, hex, and binary:

             decimal      hex                binary                 =======   ======   ===================flags (before):      131   0x0083   0000 0000 1000 0011    bit to set:        8   0x0008   0000 0000 0000 1000 flags (after):      139   0x008b   0000 0000 1000 1011

Each bit position in 'flags (after)' is a '1' if either 'flags (before)' or 'bit to set' has a '1' in the same bit position. Note that in this case the result is the same as adding: 131 + 8 = 139. But consider this case, where the inital value in 'flags' was 271 instead of 131:

             decimal      hex                binary                 =======   ======   ===================flags (before):      271   0x010f   0000 0001 0000 1111    bit to set:        8   0x0008   0000 0000 0000 1000 flags (after):      271   0x010f   0000 0001 0000 1111

The initial value of 271 already has bit 3 set, so doing a logical OR of bit 3 being set has no effect at all. This is why you can't simply add to set a particular bit to an arbitrary value.The other operators perform other logical operations in the same bitwise fashion. The logical AND operation is most often used to isolate particular bits. For instance, suppose you had an arbitrary value in a variable 'x', and you wanted to isolate just the least significant byte. A logical AND will do the trick quite nicely:

x = x & 0xff;

x &= 0xff; // exactly the same result, more concisely...

When a logical AND is used in this manner, it's often referred to as "masking" (and the value 0xff I used would be called the "mask". Here's what this operation looks like by the numbers, assuming an initial value of 1763 for 'x':

           decimal      hex                binary               =======   ======   ===================  x (before):     1763   0x06e3   0000 0110 1110 0011bits to mask:      255   0x0008   0000 0000 1111 1111   x (after):      227   0x00e3   0000 0000 1110 0011

The logical AND operator sets a '1' into any particular bit position only if both operands have a '1' in that same bit position. The 255 (0xff) "masks" the least significant 8 bits, exactly as we wanted.The last bitwise operator I'm going to talk about today is the negation operator ('~'). This operator flips every bit in the operand. You use it like this:

x = ~0xff;

And here's what it looks like by the numbers:

                   decimal      hex                binary                       =======   ======   ===================mask (before):             255   0x00ff   0000 0000 1111 1111 mask (after):      4294901760   0xff00   1111 1111 0000 0000

Yes, Paula is sorry she ever asked me about this.

But she'll be even more sorry tomorrow, when I talk about shifty bits!

View original source

https://www.servicenow.com/community/in-other-news/javascript-bitwise-operators-and/ba-p/2285489