|Written by Ian Elliot|
|Monday, 09 August 2021|
Page 2 of 2
Beyond 32 Bits
You will also be pleased to learn that, as true evaluates to 1 and false to 0, you can use the bitwise logical operators on Boolean values as long as you remember that true is 1 and false 0. For example:
var c = 0xF & (1===1);
So what do you use the bitwise logical operators for?
You often encounter the problem of setting or clearing particular bits in a value. The value is usually stored in a variable that is usually regarded as a status variable or flag. You can set and unset bits in a flag using another value usually called a mask that defines the bits to be changed. For example, if you only want to change the first (least significant) bit then the mask would be 0x01. If you wanted to change the first and second bits the mask would be 0x03 and so on.
To work out the correct hexadecimal value needed for any particular mask, you can use the parseInt function with a radix of 2. For example:
sets a to 0x01 and:
sets a to 0x03 and so on.
In general, just write down a string of 0s and 1s with a 1 in the positions you want to change and use parseInt to convert it to a mask value.
Now that you have a mask what do you do with it?
Suppose the mask contains a value that in binary has a 1 at each bit location you want to change. Then:
flag | mask;
returns a bit pattern with the bits that the mask specifies set to 1. Notice that the bits that the mask doesn't specify are left at their original values. This is often expressed as the mask sets the bits it specifies.
var mask=parseInt("11",2); var flag = 0xFFF0; var result = flag | mask;
sets result to 0xFFF3, i.e. it sets the first (least significant) two bits.
If you use:
flag & ~mask;
then the bits specified in the mask are set to 0 - or unset if you prefer. Notice that you have to apply a NOT operator to the mask.
var mask=parseInt("11",2); var flag = 0xFFFF; var result = flag & ~mask;
sets result to 0xFFFC, i.e. it unsets the first two bits.
As well as setting and unsetting particular bits, you might also want to "flip" specified bits, i.e. negate them so that if the bit was a 1 it is changed to a 0 and vice versa. You can do this using the XOR operator, so:
flag ^ mask
flips the bits specified by the mask.
var mask=parseInt("11",2); var flag = 0xFFFF; var result = flag ^ mask; alert(result.toString(16));
sets result to 0xFFFC because it changes the lower two bits from 1s to 0s. Again, bits not specified by the mask are unaffected.
Of course, in each case you don't have to use a variable to specify the mask, you could just use a numeric literal.
For example, instead of:
var flag = 0xFFFF; var result = flag ^ mask;
you can write:
var result = flag ^ 0xFFFF;
Also if you want to update the flag rather than derive a new result, you can use &=, |= and ^= to perform the update directly.
For example, instead of:
flag = flag | mask;
you can use:
flag |= mask;
What sorts of things do you use masking operations for?
One of the best known uses of bit manipulation predates HTML5 - extracting the color codes from an RGB color value. For example:
var RGBcolor=0x010203; var B=RGBcolor & 0x0000FF; var G=RGBcolor & 0x00FF00; var R=RGBcolor & 0xFF0000;
This takes an RGB value and splits it up into its components using appropriate masks.
The result is that you end up with 0x010000 stored in R, 0x000200 in G and 0x000003 in B. Notice that while the value of B is correct, R and G are incorrect and the bits need shifting to the right. This brings us to the use of the shift operators.
In Chapter but not in this extract
Now available as a paperback or ebook from Amazon.
|Last Updated ( Monday, 09 August 2021 )|