- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Recently 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 2^3, 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 0011
bits 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!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
