Reading Bits and Resetting Bits

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.

Figure 1. Variable bit is set to binary position 2.

Figure 1. Variable bit is set to binary position 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.

Figure 2. How an & (and) mask works.

Figure 2. How an & (and) mask 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.

Figure 3. The ^ (xor) operator inverts the bit field, creating a mask.

Figure 3. The ^ (xor) operator inverts the bit field, creating a mask.

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.

Leave a Reply