Once you break out the tools, bit manipulation in C can be a fascinating and useful thing. Setting a bit, covered in last week’s Lesson, is a big first step. Once you’ve done that, the functions to read and set a bit fall into place naturally.
The goal in each function is to access a specific bit. From last week’s code snippet, the following statement is used:
bit = 1 << bit;
Variable bit
represents the bit position in a byte, word, or long word. Position 0 is at the far right. Position 1 comes next, and so on. The function sets bit 0 to the value 1. The left shift operator, <<
, shifts that value left to the proper bit position.
To read a bit at a specific position, you must mask out all other bits in the value. The operator that assists in that process is the bitwise &
(and). After you mask out all the other bits, the value that remains is either zero or some other value. These two conditions evaluate to FALSE and TRUE in the C language, which tells you whether or not the bit was set.
In Figure 1, you see binary value 1 shifted twice to bit position 2, as in bit = 1 << bit;
where bit
equals 2.
Once the bit is positioned, an &
(and) mask eliminates all other bits but position 2 in the original value. The result is either 0 or 4 depending on whether the bit was off or on, respectively. Figure 2 illustrates how this operation works.
The function I wrote to read bit status is called bit_test(). It uses the same arguments as bit_set() from last week’s Lesson:
int bit_test(char bit, char byte) { bit = 1 << bit; return(bit & byte); }
The first statement sets the proper position for variable bit
. The second statement uses the &
(and) mask to isolate that bit and return the value.
The value returned by bit_test() is either true, meaning the bit was set, or false when the bit is zero.
The final bit manipulation function is bit_reset(), which resets a bit’s value to zero. This function uses the same arguments as bit_set() and bit_test(), which provides consistency.
To reset a bit, the bit_reset() function uses both the bitwise ^
(exclusive or) and &
(and) operators. These operators help to isolate the individual bit and set only that bit to 0.
Here is the function:
void bit_reset(char bit, char *byte) { bit = 1 << bit; bit ^= 0xff; *byte = *byte & bit; }
The statement bit ^= 0xff;
inverts the bits. The net effect is to mask off all bits save for the one to reset, as illustrated in Figure 3.
Once the mask is set, the &
(and) operator filters through every bit but the one to reset. The end result is that only one bit is reset.
In next week’s Lesson, I put all three functions to work in a demo program that manipulates bits in a char value.