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:
int flag = 0xFFFF;
int result = flag ^ mask;
you can write:
int 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:
int flag = flag ^ 0xFFFF;
you can use:
int flag ^= 0xFFFF;
To summarize:
create a mask that has 1 at the position of each bit you want to change.
OR the mask with the flag to set just those bits.
AND the NOT of the mask to unset just those bits.
XOR the mask to flip just those bits.
Bits in the mask that are 0 are unaffected by any of the operations.
Using Masks
What sorts of things do you use masking operations for?
Often a low-level API will require that particular bits in a status word are set or unset to make it operate in a particular way. Similarly, hardware registers are generally organized into groups of bits that you have to change to control the device.
A very common application is to extract the RGB color information from a single int representing the color of a pixel. For example:
int RGBcolor=0x010203;
int B=RGBcolor & 0x0000FF;
int G=RGBcolor & 0x00FF00;
int R=RGBcolor & 0xFF0000;
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 the value of B is correct, but R and G are incorrect - the bits need shifting to the right. This brings us to the use of the shift operators.
Not in this extract:
Shifting Values
Rotate
Testing a Bit
Endianism
Some Examples Options Overflow Free Average Computing a Checksum
Summary
There are four bitwise logical operators &, |, ^ and ~. These should not be confused with the logical operators &&, || and !.
The bitwise logical operators behave differently on signed and unsigned types.
A mask is a way of controlling which bits a bitwise operation affects.
There are two shift operators: the << arithmetic or logical shift left and >> an arithmetic shift right.
Arithmetic shift left corresponds to multiplying an integer type by 2 and an arithmetic shift right divides by 2.
Arithmetic shift right isn't exactly the same as integer division by 2 for negative values as it rounds towards negative infinity.
There is no rotate operator in C, but you can construct one.
Masks can also be used to test the state of a bit or group of bits.
There is no standard for the order in which parts of a multi-byte value are stored. Little endian stores the low-order bits first and big endian stores the high-order bits first.
Findings from GitHub show that code authored with Copilot has increased functionality and improved readability, is of better quality, and receives higher approval rates than code authored without it.