Bitwise Operations with Python

Author
Affiliation

Clayton Cafiero

University of Vermont

Published

2025-10-13

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):

Bitwise and: &

 

Here’s bitwise or, |, with the same operands:

Bitwise or: |

 

Here’s bitwise exclusive or (XOR), ^, with the same operands:

Bitwise XOR: |

 

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.

Masking low-order bits

 

If we wanted to isolate the four high-order bits we use a different mask.

Masking high-order bits

 

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.