Last modified: Apr 06, 2026 By Alexander Williams
Python Bitwise Operations Guide & Examples
Python is a high-level language. It often hides low-level details. But sometimes you need to work directly with bits. This is where bitwise operations come in.
They let you manipulate individual bits in numbers. This is crucial for tasks like networking, cryptography, and hardware control. Understanding them makes you a more versatile programmer.
What Are Bitwise Operations?
Computers store everything in binary. Binary is a base-2 number system. It uses only two digits: 0 and 1. Each digit is called a bit.
Bitwise operations work on these individual bits. They compare or change bits within integers. This is different from logical operations like and and or, which work on boolean truth values.
Python provides six main bitwise operators. They are fundamental tools for efficient code.
The Core Python Bitwise Operators
Let's explore each operator. We will use simple examples with 8-bit numbers for clarity.
Bitwise AND (&)
The AND operator compares two bits. It returns 1 only if both bits are 1. Otherwise, it returns 0.
# Bitwise AND Example
a = 12 # Binary: 00001100
b = 10 # Binary: 00001010
result = a & b
print(f"{a} & {b} = {result}")
print(f"Binary: {bin(a)} & {bin(b)} = {bin(result)}")
12 & 10 = 8
Binary: 0b1100 & 0b1010 = 0b1000
Use case: Masking. You can extract specific bits from a number. For instance, checking if a number is even (a & 1 == 0).
Bitwise OR (|)
The OR operator returns 1 if at least one of the two bits is 1.
# Bitwise OR Example
a = 12 # 00001100
b = 10 # 00001010
result = a | b
print(f"{a} | {b} = {result}")
print(f"Binary: {bin(a)} | {bin(b)} = {bin(result)}")
12 | 10 = 14
Binary: 0b1100 | 0b1010 = 0b1110
Use case: Setting flags. You can combine multiple options into a single integer value.
Bitwise XOR (^)
The XOR (exclusive OR) operator returns 1 only if the two bits are different.
# Bitwise XOR Example
a = 12 # 00001100
b = 10 # 00001010
result = a ^ b
print(f"{a} ^ {b} = {result}")
print(f"Binary: {bin(a)} ^ {bin(b)} = {bin(result)}")
12 ^ 10 = 6
Binary: 0b1100 ^ 0b1010 = 0b0110
Use case: Toggling bits or simple encryption. XORing a value twice with the same key returns the original value.
Bitwise NOT (~)
The NOT operator inverts all bits. It's a unary operator. In Python, it returns the two's complement, which can be confusing.
# Bitwise NOT Example
a = 10 # Binary: ...00001010
result = ~a
print(f"~{a} = {result}")
print(f"Binary: ~{bin(a)} = {bin(result)}")
# Understanding the result
print(f"Simplified: Invert bits of {a} ({bin(a)}) -> {bin(~a & 0xFF)} (masked to 8 bits)")
~10 = -11
Binary: ~0b1010 = -0b1011
Simplified: Invert bits of 10 (0b1010) -> 0b11110101 (masked to 8 bits)
Remember, ~x equals -x - 1. This is due to Python's infinite two's complement representation.
Bitwise Left Shift (<<)
The left shift operator moves bits to the left. It adds zeros on the right. Shifting left by n is like multiplying by 2^n.
# Bitwise Left Shift Example
a = 5 # Binary: 00000101
n = 2
result = a << n
print(f"{a} << {n} = {result}")
print(f"Binary: {bin(a)} << {n} = {bin(result)}")
print(f"Same as {a} * (2**{n}) = {a * (2**n)}")
5 << 2 = 20
Binary: 0b101 << 2 = 0b10100
Same as 5 * (2**2) = 20
Use case: Fast multiplication by powers of two or creating bit masks.
Bitwise Right Shift (>>)
The right shift operator moves bits to the right. It discards bits on the right. For positive integers, it's like integer division by 2^n.
# Bitwise Right Shift Example
a = 20 # Binary: 00010100
n = 2
result = a >> n
print(f"{a} >> {n} = {result}")
print(f"Binary: {bin(a)} >> {n} = {bin(result)}")
print(f"Same as {a} // (2**{n}) = {a // (2**n)}")
20 >> 2 = 5
Binary: 0b10100 >> 2 = 0b101
Same as 20 // (2**2) = 5
Use case: Fast division by powers of two or extracting bit fields.
Practical Applications of Bitwise Operations
Why learn this? It's not just academic. Bitwise ops solve real problems efficiently.
1. Checking Integer Parity (Even/Odd)
The least significant bit (LSB) determines if a number is even or odd. Use AND with 1.
def is_even(num):
return (num & 1) == 0
print(f"Is 15 even? {is_even(15)}")
print(f"Is 24 even? {is_even(24)}")
Is 15 even? False
Is 24 even? True
2. Setting, Clearing, and Toggling Bits
You can manipulate specific bits using masks.
# Start with a number
flags = 0b0000 # 0
# Set the 3rd bit (from right, 0-indexed)
mask_set = 1 << 2 # 0b0100
flags |= mask_set
print(f"Set 3rd bit: {bin(flags)}")
# Toggle the 1st bit
mask_toggle = 1 << 0 # 0b0001
flags ^= mask_toggle
print(f"Toggle 1st bit: {bin(flags)}")
# Clear the 3rd bit
mask_clear = ~(1 << 2) # Invert the mask
flags &= mask_clear
print(f"Clear 3rd bit: {bin(flags)}")
Set 3rd bit: 0b100
Toggle 1st bit: 0b101
Clear 3rd bit: 0b1
3. Efficient Multiplication and Division
Shifts are much faster than arithmetic operators for powers of two. This is a key optimization in performance-critical code.
value = 7
# Multiply by 8 (2^3)
fast_multiply = value << 3
slow_multiply = value * 8
print(f"Fast: {value} << 3 = {fast_multiply}")
print(f"Slow: {value} * 8 = {slow_multiply}")
print(f"Results equal? {fast_multiply == slow_multiply}")
Fast: 7 << 3 = 56
Slow: 7 * 8 = 56
Results equal? True
4. Working with Color Values (RGB)
Colors are often packed into a single integer. Bitwise ops extract the Red, Green, and Blue components.
def unpack_rgb(packed_color):
"""Extract 8-bit RGB values from a 24-bit integer."""
red = (packed_color >> 16) & 0xFF
green = (packed_color >> 8) & 0xFF
blue = packed_color & 0xFF
return red, green, blue
color = 0xFFA07A # Light Salmon
r, g, b = unpack_rgb(color)
print(f"Color #{hex(color)[2:].upper()}")
print(f"Red: {r}, Green: {g}, Blue: {b}")
Color #FFA07A
Red: 255, Green: 160, Blue: 122
Important Considerations and Best Practices
Bitwise operations are powerful but require care.
Operator Precedence: Bitwise operators have lower precedence than arithmetic ones. Always use parentheses to avoid confusion. a & b == c is interpreted as a & (b == c), which is likely wrong. Use (a & b) == c.
Negative Numbers: Be cautious with right shifts (>>) on negative numbers. The sign bit is preserved, which is called an arithmetic shift. This behavior can be unexpected.
Readability: Comment your bitwise code thoroughly. What a mask like 0x1F represents is not obvious to everyone. Clear variable names help.
For more on core Python concepts, see our guide on Python data types.
Conclusion
Python bitwise operations are essential for low-level programming. They provide fine-grained control over data.
You learned the six core operators: AND, OR, XOR, NOT, Left Shift, and Right Shift. Each has specific uses in masking, flag manipulation, and optimization.
Practical applications are vast. They range from checking parity to processing image colors. Mastering these operations unlocks new problem-solving techniques.
Start by experimenting with the examples. Try creating your own bit masks. Explore how these concepts apply in areas like networking protocols or algorithm design. The more you practice, the more intuitive bit manipulation will become.
Remember, the key is understanding the binary representation. Think in bits, and these operations will become a natural part of your Python programming toolkit.