Bitwise Operations with Python
Python’s bitwise operators >>
, <<
, &
, |
, ^
, and ~
Python, like most other programming languages, has special operators for performing bitwise operations on data. A bitwise operation is an operation that is applied to individual bits of some object. (We will defer discussion of the bitwise negation operator ~
and will take this up later.)
Bitshift right and left with >>
and <<
>>
is the bitshift right operator and <<
is the bitshift left operator. These are binary infix operators that take the value to be shifted on the left, and the number of positions to be shifted on the right. So, 4 >> 1
gets us 2, because we’ve shifted 0100
one position to the right and we get 0010
(which is decimal 2), and 4 << 1
gets us 8 because we’ve shifted 0100
one position to the left and we get 1000
(which is decimal 8).
What can be confusing is that bitshift operates on the binary representation of the object in question, but Python displays all integer values in decimal by default.
We can get the binary representation of any integer with the bin()
built-in, or with an f-string and format specifier.
>>> bin(4)
0b100
>>> f"{4:08b}"
'00000100'
What’s the difference here? The bin()
returns a binary representation of an integer argument. We see this because Python binary literals are prefixed by 0b
to indicate that they are displayed in binary. The f-string gives us a bitstring, not a number (so we can’t do arithmetic or bitwise operations with the result). In any event, we see that 4 is indeed 100 in binary (leading zeros don’t matter, and prefix aside).
If we shift right, bits fall off the right side as we shift and new zero-bits flow in from the left.
>>> n = 0b10000000
>>> n
128
>>> while n > 0:
... n >>= 1
... print(f"{n} \t{n:08b}")
...
64 01000000
32 00100000
16 00010000
8 00001000
4 00000100
2 00000010
1 00000001
0 00000000
Or we can go in the other direction, shifting left.
>>> n = 0b00000001
>>> n
1
>>> while n < 128:
... n <<= 1
... print(f"{n} \t{n:08b}")
...
2 00000010
4 00000100
8 00001000
16 00010000
32 00100000
64 01000000
128 10000000
Bitwise logical operations with &
, |
, and ^
We’ve seen the Boolean operators and
and or
. &
and |
are bitwise logical operators that apply logical and or logical or to individual bits, respectively. ^
is the bitwise exclusive or (XOR).
These go bit-by-bit, performing logical and, logical or, or logical XOR on the two operands.
Here’s bitwise and, &
, with two 8-bit operands (we’ll just ignore higher order bits):
&
Here’s bitwise or, |
, with the same operands:
|
Here’s bitwise exclusive or (XOR), ^
, with the same operands:
|
Let’s test these in the Python shell:
>>> a = 0b00110101
>>> a
53
>>> b = 0b01001111
>>> b
79
>>> a & b
5
>>> bin(a & b)
'0b101'
>>> a | b
127
>>> bin(a | b)
'0b1111111'
>>> a ^ b
122
>>> bin(a ^ b)
'0b1111010'
So that all checks out!
Isolating a bit or bits with &
Sometimes we want to isolate bits in some value. For this we can use &
. Let’s say we wanted to isolate the four low-order bits in a value. We’d create a mask, with 1s in the positions in question, and then apply &
with the mask.
If we wanted to isolate the four high-order bits we use a different mask.
To isolate a single bit, we simply use a mask with a single 1 in the position in question and apply &
.
© 2025 Clayton Cafiero.
No generative AI was used in writing this material. This was written the old-fashioned way.