Bitwise Operators
Pretty much everything in a computer is represented by a series of 1s and 0s called 'bits'. Bitwise operations directly manipulate these bits.
The Base 2 Number System
The counting that you would normally do every day is done in base 10, meaning that each place in the number can hold one of ten values (0 to 9).
In binary, counting is done in base 2, meaning that each place can hold one of two values (0 or 1). The counting pattern is similar as for base 10, with the only difference being when you carry over to a new column (i.e. going higher than 9 in base 10), you have to carry over every time a place goes higher than 1.
In base 2 for example, once you reach the number 2 you have to carry over the one, resulting in the representation '10'. Adding another 1 results in '11' (3), and another 1 gets you to '100' (4).
While in base 10, each decimal place represents a power of 10, each place in a binary number represents a power of 2 (a bit). The rightmost bit is the 1's bit (or 20), the next is the 2's bit (21), then 4, 8, 16, 32, etc.
The binary number '1010' is 10 in base 2 because the 8's bit and the 2's bit are flipped 'on':
8s 4s 2s 1s
1 0 1 0
8 + 0 + 2 + 0 = 10
A few more examples:
01 = 1
010 = 2
011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
Bitwise Operators: Slide Left and Right
These operators work by shifting the bits of a number over by a designated number of slots. The mathematical equivalent is floor dividing and multiplying by 2 for every time you shift, but visually just think of it as shifting the 1s and 0s by the specified number of slots.
# Left Bit Shift (<<)
0b000001 << 2 == 0b000100 (1 << 2 = 4)
0b000101 << 3 == 0b100001 (5 << 3 = 40)
# Right Bit Shift (>>)
0b0010100 >> 3 == 0b000010 (20 >> 3 = 2)
0b0000010 >> 2 == 0b000000 (2 >> 2 = 0)
Bitwise Operators: AND
The AND (&) operator compares two numbers at the bit level and returns a number where the bits are turned 'on' if the corresponding bits of both numbers are 1:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
# Example:
a: 00101010 42
b: 00001111 15
a & b: 00001010 10
This means that using the & operator will always return a number that is less than or equal to the smaller of the two values.
Bitwise Operators: OR
The OR ( | ) operator is very similar to the AND operator, except that the bits of the resulting number are turned 'on' if either of the corresponding bits are 1:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
# Example:
a: 00101010 42
b: 00001111 15
a & b: 00101111 47
Opposite to AND, the OR operator can only create results that are greater than or equal to the larger of the two inputs.
Bitwise Operators: XOR
The exclusive OR ( ^ ) operator again compares two numbers, but this operator returns a number where the bits are turned 'on' if either of the corresponding bits of the two numbers are 1 but not both:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 0
# Example:
a: 00101010 42
b: 00001111 15
a & b: 00100101 37
Bear in mind that if a bit is off in both numbers, it stays off in the resulting number. XORing a number with itself will always return 0.
Bitwise Operators: NOT
This operator (~) simply flips all the bits in a single number (mathematically this is the same as adding one to the number and then making it negative):
~1 = -2
~2 = -3
~3 = -4
~42 = -43
The Bit Mask
A bit mask is a variable that aids you with bitwise operations. It can help turn bits on / off, or collect data from an integer about which bits are already on / off.
For example, if you want to see if the third bit from the right is on:
1. Create a variable num containing the number 12 (0b1100)
2. Create a mask with the third bit 'on'
3. Use AND to see if the third bit from the right of the num is on
4. If desired is greater than zero, then the third bit of num must be 1.
num = 0b1100
mask = 0b0100
desired = num & mask
if desired > 0:
print "Bit was on"