Bitwise operators let you work directly with the binary representation of integers. Rather than treating a number as a single value, they treat it as a sequence of bits and apply logical or shift operations to each bit position independently.
What's in this Python Tutorial▼
Python supports six bitwise operators: & (AND), | (OR), ^ (XOR), ~ (NOT), << (left shift), and >> (right shift). They work exclusively on integers. Understanding them opens the door to efficient flag manipulation, compact data storage, low-level algorithm design, and a clearer understanding of how computers handle numbers internally.
Binary Representation Refresher
Every Python integer has an underlying binary representation — a sequence of 1s and 0s. The rightmost bit is the least significant bit (LSB) and represents 20. Each position to the left doubles in value. You can inspect any integer's binary form with the built-in bin() function.
print(bin(5)) # 0b101 (4 + 0 + 1)
print(bin(9)) # 0b1001 (8 + 0 + 0 + 1)
print(bin(12)) # 0b1100 (8 + 4 + 0 + 0)
# bin() always prefixes the result with '0b'
# Strip it if you want a plain string:
print(bin(5)[2:]) # '101'
Python integers have arbitrary precision — they are not limited to 8, 16, or 32 bits the way integers are in C or Java. The bitwise operators still work correctly regardless of size, and Python handles negative integers using two's complement arithmetic internally.
The Six Bitwise Operators
The table below summarises all six operators. Each is explained in detail in the accordion that follows.
| Operator | Symbol | Description | Example |
|---|---|---|---|
| AND | & | 1 if both bits are 1 | 5 & 3 → 1 |
| OR | | | 1 if at least one bit is 1 | 5 | 3 → 7 |
| XOR | ^ | 1 if exactly one bit is 1 | 5 ^ 3 → 6 |
| NOT | ~ | Inverts all bits | ~5 → -6 |
| Left shift | << | Shifts bits left, fills right with 0s | 5 << 1 → 10 |
| Right shift | >> | Shifts bits right, discards right bits | 5 >> 1 → 2 |
- Rule
- Output bit is 1 only when both corresponding input bits are 1. Otherwise 0.
- Example
5 & 3→0b101 & 0b011→0b001→1- Common use
- Masking — isolate specific bits to test whether a flag is set.
- Rule
- Output bit is 1 when at least one of the corresponding input bits is 1.
- Example
5 | 3→0b101 | 0b011→0b111→7- Common use
- Setting flags — turn on a specific bit without changing others.
- Rule
- Output bit is 1 when the two input bits differ. 0 when they are the same.
- Example
5 ^ 3→0b101 ^ 0b011→0b110→6- Common use
- Toggling flags, swapping variables without a temporary, and simple checksums.
- Rule
- Inverts every bit. For integer x the result is -(x + 1).
- Example
~5→-6~0→-1- Common use
- Creating inverse masks and computing two's complement negation.
- Rule
- Shifts all bits left by n positions, inserting zeros on the right. Equivalent to multiplying by 2n.
- Example
5 << 1→0b1010→101 << 4→16- Common use
- Fast power-of-two multiplication, building bitmasks, encoding packed data.
- Rule
- Shifts all bits right by n positions, discarding bits that fall off the right. Equivalent to floor division by 2n for positive integers.
- Example
20 >> 2→57 >> 1→3- Common use
- Fast power-of-two division, extracting specific byte fields from packed integers.
a = 12 # 0b1100
b = 10 # 0b1010
print(a & b) # 8 — 0b1000 (both bits 1 only in position 3)
print(a | b) # 14 — 0b1110 (1 in any position where either has 1)
print(a ^ b) # 6 — 0b0110 (1 only where bits differ)
print(~a) # -13 — inverts all bits, result is -(12+1)
print(a << 2) # 48 — shifts 1100 left two positions → 110000
print(a >> 1) # 6 — shifts 1100 right one position → 0110
Build the expression that uses XOR to toggle bit 3 (value 8) in the variable flags:
^) toggles a bit — if it was 0 it becomes 1, and if it was 1 it becomes 0. Using flags ^ 8 targets bit 3 (23 = 8) specifically. AND would only clear or keep the bit; OR would only set it; ~flags would invert every bit, not just one.
Bitmasks and Flag Operations
One of the most practical applications of bitwise operators is using integers as compact sets of boolean flags. A single integer can store many independent on/off states, with each bit position representing a different flag. This pattern is common in systems programming, network protocols, and game development.
# Define flags using left shift for readability
READ = 1 << 0 # 0b0001 = 1
WRITE = 1 << 1 # 0b0010 = 2
EXECUTE = 1 << 2 # 0b0100 = 4
# Start with no permissions
perms = 0
# Set READ and WRITE flags using OR
perms = perms | READ | WRITE
print(bin(perms)) # 0b11 (read and write are on)
# Test if EXECUTE flag is set using AND
if perms & EXECUTE:
print("execute: on")
else:
print("execute: off") # prints this
# Toggle WRITE flag using XOR
perms = perms ^ WRITE
print(bin(perms)) # 0b1 (only read remains)
# Clear READ flag using AND with NOT mask
perms = perms & ~READ
print(perms) # 0 (no permissions)
Python's enum.Flag and enum.IntFlag classes wrap this bitmask pattern in a named, readable API. For production code that uses many flags, they are worth exploring — but understanding the raw bitwise operators first makes the enum behaviour intuitive.
XOR Swap Trick
XOR has the interesting property that a ^ a == 0 and a ^ 0 == a. These two facts make it possible to swap two integers without a temporary variable, though in Python the idiomatic tuple swap a, b = b, a is clearer in practice.
x = 15
y = 9
x = x ^ y # x now holds original x XOR original y
y = x ^ y # y now holds original x
x = x ^ y # x now holds original y
print(x, y) # 9 15
The function below should return True if the READ flag (bit 0) is set in perms. One line is wrong. Find it.
perms | READ to perms & READ. The OR operator (|) sets a bit regardless of whether it was already set, so perms | READ is always non-zero for any value of perms since READ equals 1. You need AND (&) to test whether a specific bit is already set — it produces a non-zero value only when that bit is 1 in both operands.
How to Use Bitwise Operators in Python
The following steps walk through the full process of using bitwise operators to test, set, clear, and toggle individual bits in an integer.
-
Understand the binary representation
Use
bin(value)to inspect the binary form of any integer before writing a bitwise expression. This confirms which bit positions are currently set and which are clear, preventing off-by-one errors when building masks. -
Apply the operator to two integers
Write an expression such as
a & b,a | b, ora ^ b. Python evaluates the operation bit by bit across the binary representations of both values and returns a new integer. -
Use a bitmask to isolate or modify bits
Define a mask integer — often written as
1 << nto target bit n — then combine it with&to test a flag,|to set a flag,^to toggle a flag, or& ~maskto clear a flag. -
Use shift operators to multiply or divide by powers of two
Use
<<to shift bits left (each position is a multiplication by 2) or>>to shift bits right (each position is a floor division by 2). This avoids explicit multiplication when the divisor or multiplier is a known power of two.
"Integers support additional operations that make sense only for bit strings." — Python Language Reference
Key Takeaways
- Python's six bitwise operators (
&,|,^,~,<<,>>) all work on integers and process each bit position independently. - AND tests bits, OR sets bits, XOR toggles bits, and combining AND with NOT (
& ~mask) clears bits — these four patterns cover the majority of flag manipulation tasks. - Left shift multiplies by powers of two; right shift performs floor division by powers of two — both faster than the
*and//operators at the CPU level. - Bitwise NOT on a positive integer
xalways produces-(x + 1)due to Python's two's complement integer representation.
Mastering bitwise operators gives you direct control over individual bits in an integer. That precision pays off in networking code that works with IP address fields, cryptography implementations, game state compression, and any context where packing multiple boolean values into a single integer saves memory or improves throughput.
Frequently Asked Questions
Python has six bitwise operators: & (AND), | (OR), ^ (XOR), ~ (NOT), << (left shift), and >> (right shift). Each operates directly on the binary representation of an integer.
Python does not have a && operator. The single & is a bitwise AND that operates on each pair of bits independently. Python uses the keyword and (lowercase) for logical boolean AND, which short-circuits evaluation.
The ~ (bitwise NOT) operator inverts all bits of an integer. For a value x, the result is -(x + 1). For example, ~5 returns -6 because Python integers use two's complement representation.
XOR (^) is used to toggle specific bits, swap two integers without a temporary variable, detect which bits differ between two values, and in cryptography and checksum algorithms where its self-inverse property (a ^ b ^ b == a) is useful.
The left shift operator << shifts all bits of an integer to the left by a given number of positions, filling the right side with zeros. Each left shift by one position is equivalent to multiplying the value by 2. For example, 3 << 2 equals 12 because 3 × 22 = 12.
The right shift operator >> shifts all bits to the right by a given number of positions. Bits shifted off the right end are discarded. For positive integers, each right shift by one is equivalent to floor division by 2. For example, 12 >> 2 equals 3.
No. Python's bitwise operators only work on integers. Applying them to floats raises a TypeError. If you need to manipulate the binary representation of a float, you would first need to use the struct module to pack it into bytes, then operate on those integer byte values.
A bitmask is an integer used with bitwise operators to select, set, clear, or toggle specific bits in another integer. For example, using & with a mask of 0xFF extracts the lowest 8 bits of any integer. Masks are often defined with 1 << n to target a specific bit position n.