Bitwise operators are used for performing operations on operations on Binary pattern or Bit sequences. Python has 6 bitwise operators: AND, OR, XOR, Complement and Shift Operators. They normally operate on numbers but instead of treating them as numbers they are treated as string of bits, written in twos complement binary by the operators.
Let’s go through go through a brief summary of twos compliment to make you understand better:
Two’s Representation of Positive numbers
Positive numbers have a pretty straight forward representation:
- 0 can be represented as ‘0’
- 1 can be represented as ‘1’
- 2 can be represented as ’10’
- 3 can be represented as ’11’
- 1025 is ‘10000000001’ is == 2**10 + 2**0 == 1024 + 1
Two’s Representation of Negative numbers
Negative numbers are written with a leading one instead of a leading zero. So if you are using only 8 bits for your twos-complement numbers, then you treat patterns from “00000000” to “01111111” as the whole numbers from 0 to 127, and reserve “1xxxxxxx” for writing negative numbers.
Using only 8 bits for twos-compliment negative numbers can be represented as:
- -x can be represented as the complement of the bit pattern for (x-1)
- So -2 is the ~(2-1) == ~(1) == “11111101”
Python doesn’t use 8-bit numbers. It USED to use however many bits were native to your machine, but since that was non-portable, it has recently switched to using an INFINITE number of bits. Thus the number -5 is treated by bitwise operators as if it were written: “…1111111111111111111011”.
Phew!! Now that the hard part is over lets jump to Bitwise Operators
BitWise Operators Table
|AND||a & b||Does a “bitwise and“. Each bit of the output is 1 if the corresponding bit of a AND of b is 1, otherwise it’s 0.|
|OR||a | b||Does a “bitwise or”. Each bit of the output is 0 if the corresponding bit of a AND of b is 0, otherwise it’s 1.|
|XOR||a ^ b||Does a “bitwise exclusive or“. Each bit of the output is the same as the corresponding bit in a if that bit in b is 0, and it’s the complement of the bit in a if that bit in b is 1.|
|Compliment||~ a||Returns the complement of a – the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -a – 1.|
|Left Shift||a << b||Returns a with the bits shifted to the left by b places (and new bits on the right-hand-side are zeros). This is the same as multiplying a by 2**b.|
|Right Shift||a >> b||Returns a with the bits shifted to the right by y places. This is the same as //’ing a by 2**b.|
Bitwise NOT/Complement Operator
The bitwise NOT, or complement, is a unary operation that performs logical negation on each bit, forming the ones’ complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0. Let’s see a few Examples:
NOT x = -x − 1
>>> bin(3) '0b11' >>> bin(~3) '-0b100' >>> ~3 -4
Bitwise not operator can also be used to invert a gray scale image which is stored as an unsigned integer.
Bitwise AND Operator
A bitwise AND takes two equal-length binary representations and performs the logical AND operation on each pair of the corresponding bits, which is equivalent to multiplying them. Thus, if both bits in the compared position are 1, the bit in the resulting binary representation is 1 (1 × 1 = 1); otherwise, the result is 0 (1 × 0 = 0 and 0 × 0 = 0). For example:
>>> bin(0b110 & 0b011) # 6 & 3 '0b10' >>> 0b110 & 0b011 2 >>> 6 & 3 2
AND Operator can be used to quickly test divisibility by 2
>>> 6 & 1 # Even 0 >>> 8 & 1 # Even 0 >>> 11 & 1 # Odd 1
Bitwise OR Operator
A bitwise OR takes two bit patterns of equal length and performs the logical inclusive OR operation on each pair of corresponding bits. The result in each position is 0 if both bits are 0, while otherwise the result is 1. For example:
>>> bin(0b110 | 0b011) # 6 | 3 '0b111' >>> 0b110 | 0b011 7 >>> 6 | 3 7
Bitwise XOR Operator
A bitwise XOR takes two-bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1. In this we perform the comparison of two bits, being 1 if the two bits are different, and 0 if they are the same. For example:
>>> bin(0b110 ^ 0b011) # 6 ^ 3 '0b101' >>> 0b110 ^ 0b011 5 >>> 6 ^ 3 5
Assembly language programmers and optimizing compilers sometimes use XOR as a short-cut to setting the value of a register to zero. Performing XOR on a value against itself always yields zero, and on many architectures this operation requires fewer clock cycles and memory than loading a zero value and saving it to the register.
Leftward Shift Operator
A leftward Shift Operator shifts the bits left y places and zeroes are shifted in to fill the discarded bits. Let’s see an image that will make you understand it better:
Here the bits are shifted 1 place and a zero is filled at the end. This is same as multiplying a number by 2. See for yourself in this example:
>>> 3<<1 # x<<y y is the shift --> 3*2 6 >>> 3<<2 # 3*2**2 12 >>> 3<<2 # 3*2**3 24 >>> bin(3) '0b11' >>> bin(6) '0b110'
Rightward Shift Operator
A Rightward Shift Operator shifts the bits right y places and zeroes are shifted in to fill the discarded bits. Let’s see an image that will make you understand it better:
Here the bits are shifted 1 place and a zero is filled at the end. This is
>>> bin(3) '0b11' >>> bin(6) '0b110' >>> 6>>1 # '110' -> '011' 1 place shift 3 >>> 6>>2 # '110' -> '001' 2 place shift 1 >>> 6//2 3 >>> 6//4 1
Voila!! We are done. In case if you face any problem please comment below. I will be happy to help.
Practice Makes you perfect!!
Here are few questions which you can use to practice bitwise operators problems:
More questions are added daily with its approach and best solution. Subscribe to our site to be updated for new posts and keep learning.