Bitwise Operators in Python (AND, OR, XOR, NOT, SHIFT)
Python provides the bitwise operators, &(AND), |(OR), ^(XOR), ~(NOT, invert), <<(LEFT SHIFT), >>(RIGHT SHIFT).
For more information about converting binary, octal, and hexadecimal numbers and strings using bin(), oct(), hex(), and format(), see the following articles.
See the following article on how to count the number of 1s in binary representation for integer int.
For Boolean operations on bool types (True, False) instead of bitwise operations, see the following article. Use and and or instead of & and |.
Inputs and outputs for AND, OR, and XOR
The inputs and outputs for each bit of AND, OR, and XOR are as follows.
| Input 1 | Input 2 | AND | OR | XOR |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 1 | 1 |
| 0 | 0 | 0 | 0 | 0 |
Bitwise AND: &
Bitwise AND with the & operator:
x = 12 # 0b1100
y = 10 # 0b1010
print(x & y)
print(bin(x & y))
# 8
# 0b1000
Bitwise OR: |
Bitwise OR with the | operator:
x = 12 # 0b1100
y = 10 # 0b1010
print(x | y)
print(bin(x | y))
# 14
# 0b1110
Bitwise XOR: ^
Bitwise XOR with the ^ operator:
x = 12 # 0b1100
y = 10 # 0b1010
print(x ^ y)
print(bin(x ^ y))
# 6
# 0b110
Bitwise operations with negative integers
Bitwise operations on negative integers are handled as if the values were expressed in two's complement.
Note that converting a negative integer to a binary string using bin() or format() results in a minus sign rather than the two's complement format.
x = -9
print(x)
print(bin(x))
# -9
# -0b1001
To get a string expressed in two's complement representation, perform the bitwise AND & with the maximum number of digits required. For example, use 0b1111 (= 0xF) for 4-bit, 0xFF for 8-bit, and 0xFFFF for 16-bit.
print(bin(x & 0xFF))
print(format(x & 0xFF, 'b'))
# 0b11110111
# 11110111
Keep in mind that leading zeros are omitted unless zero-padding is specified.
print(bin(x & 0b1111))
print(format(x & 0b1111, 'b'))
# 0b111
# 111
print(format(x & 0b1111, '#06b'))
print(format(x & 0b1111, '04b'))
# 0b0111
# 0111
Bitwise NOT, invert: ~
The ~ operator yields the bitwise inversion. The bitwise inversion of x is defined as -(x+1).
If the input value x is regarded as two's complement and all bits are inverted, the result is equivalent to -(x+1).
Converting ~x to a string does not yield a string with the bits of the original value inverted.
x = 9 # 0b1001
print(~x)
print(bin(~x))
# -10
# -0b1010
By applying the AND operation to create a string in two's complement representation, you can obtain a string with the inverted bits. For example, to get a 4-digit bit inverted string, specify '04b' with format() and pad it with zeros.
print(bin(~x & 0xFF))
print(format(~x & 0b1111, '04b'))
# 0b11110110
# 0110
Bit shifts: <<, >>
Left shift and right shift with operators <<, >>:
x = 9 # 0b1001
print(x << 1)
print(bin(x << 1))
# 18
# 0b10010
print(x >> 1)
print(bin(x >> 1))
# 4
# 0b100
For negative values, the sign bit is extended and shifted, and negative values are treated as having an infinite number of ones on the left side.
x = -9
print(bin(x))
print(bin(x & 0xFF))
# -0b1001
# 0b11110111
print(x << 1)
print(bin(x << 1))
print(bin((x << 1) & 0xFF))
# -18
# -0b10010
# 0b11101110
print(x >> 1)
print(bin(x >> 1))
print(bin((x >> 1) & 0xFF))
# -5
# -0b101
# 0b11111011
Understanding bit shifts for negative values as numerical values can be challenging; it's more intuitive to consider them as two's complement strings.