Linux C Programming Tutorial Part 13 - Bitwise Operators (Basics)

Up until now in this ongoing C programming tutorial series, we have discussed multiple kinds of operators, like arithmetic, logical, relational, and assignment. However, there's another kind of operators that are very integral to the C programming language. We are talking about bitwise operators.

As you might already know by now, every variable you use in your C program is stored in the form of bytes in memory. Further, these bytes are divided into 8 bits each. A bit can either be 1 or 0. For example, if a is a short integer (which occupies two bytes) with value 1, then on memory level, here's how a is represented:

00000000 00000001

Similarly, if b is 3, then here's how it's represented in memory:

00000000 00000011

Note: Head here to learn more about how integers are represented in the form of bits in memory.

The Bitwise operators which we're about to discuss here work on these bits. Let's start with the bitwise AND operator, which is represented by &. It takes two equal-length binary representations and performs a logical AND operation on corresponding bits.

In logical AND operation, only when both corresponding bits are 1, the result is 1. Else, the result is 0. So if you do the following:

a & b

Where 'a' is 1 and 'b' is 3 (as described in the beginning of this tutorial), then the operation yields the following result:

00000000 00000001

This is because if you logically AND the bit representations of 'a' and 'b', only the rightmost bit remains '1' and all other bits become '0'.  In integer (or more precisely, decimal) form, this bits representation turns out to be '1'.

Here's the code for this operation:

#include <stdio.h>

int main()
{
short a = 1;
short b = 3;
printf("a & b = %i", a&b);

return 0;
}

And here's the output of this code:

a & b = 1

Just like &, there are other bitwise operators. Here's the complete list:

&  - AND
| - inclusive OR
^ - exclusive OR
<< - left shift
>> - right shift
~ - one's complement or NOT

The OR operator (|) performs logical inclusive OR operation on corresponding bits of its operands - if any of the bits is 1, the resulting bit is also 1, else the resulting bit is 0. The exclusive OR (or XOR) operator works pretty much like the OR operator, just that the resulting bit is 0 if both bits are 0 or 1.

The left shift operator shifts the bits number of times specified by the second operand. For example, the following line makes sure the bits of 'a' get shifted to the left 3 times.

a << 3

If 'a' was short integer with value 1, then it's bit representation was something like:

00000000 00000001

But after the left shift operation, it's bit representation became:

00000000 00001000

So you can see, every bit shifted 3 times, bringing bit with value '1' to the fourth position (and filling vacant bit positions with '0's). So now, the decimal value of 'a' becomes 8.

On the same lines, the right shift operator (>>) shifts the bits to right. Lastly, the one's complement or NOT operator - which is the only unary operator in this list - inverses all the bits (or performs logical negation on each bit) of the operand. For example, if 'a' is a one byte variable, and is represented in the following way in memory:

11111110

Then, ~a will make it:

00000001

Note that bitwise operators can only be applied to char, short, int, and long variables (both signed and unsigned).

Conclusion

I hope I was able to make the basic concept of bitwise operators clear. Of course, there are some scenarios like applying shift operators on signed values as well as practical examples of bitwise operators that we didn't cover here. But those will definitely be covered in an upcoming tutorial. view as pdf | print