Saturday, May 25, 2024 05:17

Bitwise operators

Any programmer knows that computers can only process information represented by a series of binary numbers (1 and 0). This means that when we store the number 55 in memory of the computer, it actually stores a series of bits represented as 00110111. Bitwise operators were created to perform operations on the binary representation of a number, not its decimal representation which humans use daily.

The reason why binary representation is convenient is because having only two values, 0 and 1, these values can be implemented in Boolean circuits. In electronics, including computer chips, 1 is represented by “having electricity”, or +5V, while a 0 means “no electricity”, ground, or -5V. We will later on examine in depth these concepts, but for now, just remember computer express anything by using binary numbers, and bitwise operators can be used to perform arithmetic directly on these values.

Because, virtually, they both accept only two values as operands and results (0 or 1, true or false), bitwise operators are similar to the logical ones. You may be wondering how this is possible, logical operators deal with true or false, while bitwise operators deal with 0 and 1This is because, in programming, these values are often interchangeable, at concept level.  We can say a binary value is “false”, when is 0, and “true” when it’s 1. Of course, you cannot use Boolean values for bitwise calculations, you need to provide bits, not booleans, but the principles are similar. What applies to booleans, applies to bits too. For example, bitwise operators have 4 operations: AND (&), OR (|), XOR (^) and NOT (~), just like the logical ones.

As you can see, the above table and values are quite similar to the table of the logical operators. The only difference is in the notation the two concepts use, for instance, the logical OR is &&, while the bitwise one is &, or that the logical NOT is !, while the bitwise one is ~, also known as bitwise complement operator.

Still, you should know that here the similarities between the logical and bitwise operators stop. Unlike the logical ones, bitwise operators have two additional operations: bit shift left (<<) and bit shift right (>>).  On numerical values, these operations move the bits of the value to the left or right, and you should remember that the bits that fall outside the number are lost forever and replaced by 0.

The way bit shifting operation is performed is as follows: on the left of the operator, we place the number we want to perform the operation upon,  while on the right we place a number indicating how many bits we want to offset. As an example, 3 << 2  means that we want to move the bits of the number three to the left twice. If you lookup a decimal – binary table, you will notice that number three is represented in binary as 0000 0011. After we perform the bit shift operation, the new binary number will be 0000 1100, because we moved the bits by an offset of 2, to the left. Looking up the same binary-decimal table, you will see that 0000 1100 in decimal is 12.

To better imagine the losing of bits, imagine the same initial number 0000 0011 (3), on which we perform a bit shift operation to the right, by an offset of 1: 3 >> 1 . In this case, 0000 0011 (3) will become 0000 0001 (1), losing a significant bit.

As a concept, bitshifting operation can be imagined as multiplication (bit shifting left) or division (bit shifting right) by a power of 2. This is because of the actual nature of the binary system itself, which having only 2 values, uses powers of 2 to represent multiplication and division.

The concepts explained in this lesson are also shown visually as part of the following video:

EXERCISES
1. Write an expression that checks whether the third bit in a given integer is 1 or 0.

Solution

Guidelines: Use bitwise AND on the current number and the number that has 1 only in the third bit (i.e. number 8, if bits start counting from 0).