Bit masking is simply the process of storing data truly as bits, as opposed to storing it as chars/ints/floats. It is incredibly useful for storing certain types of data compactly and efficiently.
The idea for bit masking is based on boolean logic. For those not familiar, boolean logic is the manipulation of 'true' (1) and 'false' (0) through logical operations (that take 0s and 1s as their argument). We are concerned with the following operations:
- NOT a - the final value is the opposite of the input value (1 -> 0, 0 -> 1)
- a AND b - if both values are 1, the final value is 1, otherwise the final value is 0
- a OR b - if either value is 1, the final value is 1, otherwise the final value is 0
- a XOR b - if one value is 1 and the other value is 0, the final value is 1, otherwise the final value is 0
In computing, one of these true/false values is a bit. Primitives in C (
float, etc) are made up of some number of bits, where that number is a multiple of 8. For example, an
int may be at least 16 bits in size, where a
char may be 8 bits. 8 bits is typically referred to as a byte. C guarantees that certain primitives are at least some number of bytes in size. The introduction of
stdint.h in C11 allows the programmer to specify integer types that are exactly some number of bytes, which is extremely useful when using masks.
Bit masks are often used when setting flags. Flags are values that can be in two states, such as 'on/off' and 'moving/stationary'.
Setting bit n
n is as simple as ORing the value of the storage variable with the value
storage |= 1 << n;
As an example, here is the setting of bit 3 where
storage is a char (8 bits):
2^n logic places the '1' value at the proper bit in the mask itself, allowing access to that same bit in the storage variable.
Clearing bit n
n is the result of ANDing the value of the storage variable with the inverse (NOT) of the value
storage &= ~(1 << n);
Here's the example again:
Flipping bit n
n is the result of XORing the value of the storage variable with
storage ^= 1 << n;
Checking bit n
Checking a bit is ANDing the value of
2^n with the bit storage:
bit = storage & (1 << n);
Use bit masks to manipulate some flags.