Python Bitwise Operators Tutorial

Final Exam & Certification

Complete this tutorial and pass the 10-question final exam to earn a downloadable certificate of completion.

skip to exam

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.

python
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'
Note

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 15 & 31
OR|1 if at least one bit is 15 | 37
XOR^1 if exactly one bit is 15 ^ 36
NOT~Inverts all bits~5-6
Left shift<<Shifts bits left, fills right with 0s5 << 110
Right shift>>Shifts bits right, discards right bits5 >> 12
Rule
Output bit is 1 only when both corresponding input bits are 1. Otherwise 0.
Example
5 & 30b101 & 0b0110b0011
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 | 30b101 | 0b0110b1117
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 ^ 30b101 ^ 0b0110b1106
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 << 10b101010    1 << 416
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 >> 25    7 >> 13
Common use
Fast power-of-two division, extracting specific byte fields from packed integers.
python
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
bitwise visualizer interactive — edit values below
code builder click a token to place it

Build the expression that uses XOR to toggle bit 3 (value 8) in the variable flags:

your code will appear here...
8 flags & ^ | ~flags
Why: XOR (^) 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.

python
# 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)
Pro Tip

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.

python
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
spot the bug click the line that contains the bug

The function below should return True if the READ flag (bit 0) is set in perms. One line is wrong. Find it.

1 READ = 1 << 0
2 def has_read(perms):
3 return perms | READ != 0
4
5 print(has_read(4)) # should print False
6 print(has_read(3)) # should print True
The fix: Change 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.

  1. 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.

  2. Apply the operator to two integers

    Write an expression such as a & b, a | b, or a ^ b. Python evaluates the operation bit by bit across the binary representations of both values and returns a new integer.

  3. Use a bitmask to isolate or modify bits

    Define a mask integer — often written as 1 << n to target bit n — then combine it with & to test a flag, | to set a flag, ^ to toggle a flag, or & ~mask to clear a flag.

  4. 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

  1. Python's six bitwise operators (&, |, ^, ~, <<, >>) all work on integers and process each bit position independently.
  2. 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.
  3. 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.
  4. Bitwise NOT on a positive integer x always 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.

check your understanding question 1 of 5

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.

Certificate of Completion
Final Exam
Pass mark: 80% · Score 80% or higher to receive your certificate

Enter your name as you want it to appear on your certificate, then start the exam. Your name is used only to generate your certificate and is never transmitted or stored anywhere.

Question 1 of 10