Web Analytics

Bitwise Operators

Intermediate ~20 min read

Bitwise operators work directly on the binary representation of numbers, manipulating individual bits. While they might seem low-level, they're essential for permission systems, flags, cryptography, and performance optimizations!

Understanding Binary Numbers

Before diving into bitwise operators, let's understand how numbers are represented in binary. Each digit (bit) can be 0 or 1, and each position represents a power of 2.

Output
Click Run to execute your code
Key Point: Python prefixes binary numbers with 0b. Use bin() to convert decimal to binary, and int('1010', 2) to convert binary strings to decimal.

The Six Bitwise Operators

Python has six bitwise operators that work on the binary representation of integers.

Operator Name Description Example
&AND1 if BOTH bits are 15 & 3 = 1
|OR1 if AT LEAST ONE bit is 15 | 3 = 7
^XOR1 if bits are DIFFERENT5 ^ 3 = 6
~NOTInverts all bits~5 = -6
<<Left ShiftShifts bits left (multiply by 2^n)5 << 1 = 10
>>Right ShiftShifts bits right (divide by 2^n)5 >> 1 = 2
Output
Click Run to execute your code
Visual Tip: Line up the binary digits vertically when working with bitwise operations. Compare each column independently: AND needs both 1s, OR needs at least one 1, XOR needs exactly one 1.

Bit Shifting

Shift operators move all bits left or right by a specified number of positions. This is equivalent to multiplying or dividing by powers of 2!

Output
Click Run to execute your code
Caution: Right shifting a negative number in Python preserves the sign (arithmetic shift). Also, shifting by negative amounts or extremely large values can cause unexpected results. Always validate your shift amounts!

Practical Applications

Bitwise operators are commonly used for permission systems, flags, efficient math, and clever algorithms.

Output
Click Run to execute your code
Common Uses:
  • n & 1 - Check if odd (faster than n % 2)
  • n << 1 - Multiply by 2 (faster than n * 2)
  • flags | FLAG - Set a flag
  • flags & ~FLAG - Clear a flag
  • flags ^ FLAG - Toggle a flag

Common Mistakes

1. Confusing & with and, | with or

# Wrong - these are different!
if a & b:  # Bitwise AND (compares bits)
if a and b:  # Logical AND (checks truthiness)

# Examples:
a, b = 2, 4
print(a & b)   # 0 (no common bits)
print(a and b) # 4 (both truthy, returns last)

2. Forgetting operator precedence

# Wrong - comparison has higher precedence!
if x & 1 == 1:  # Parsed as: x & (1 == 1) โ†’ x & True โ†’ x & 1
    pass

# Correct - use parentheses
if (x & 1) == 1:
    pass

3. Unexpected NOT (~) results

# Surprise! NOT doesn't give what you might expect
x = 5
print(~x)  # -6, not what you might expect!

# This is because Python uses two's complement
# ~x = -(x + 1) for all integers

4. Using ^ for exponentiation

# Wrong - ^ is XOR, not power!
result = 2 ^ 3  # 1 (XOR), not 8!

# Correct - use ** for exponentiation
result = 2 ** 3  # 8

Exercise: Permission System

Task: Implement a permission system using bitwise operators.

Requirements:

  • Grant READ and WRITE permissions using OR (|)
  • Check if user has WRITE permission using AND (&)
  • Revoke WRITE permission using AND (&) and NOT (~)
  • Toggle EXECUTE permission using XOR (^)
Output
Click Run to execute your code
Show Solution
# Permission flags
READ_PERMISSION = 4     # 100
WRITE_PERMISSION = 2    # 010
EXECUTE_PERMISSION = 1  # 001

user_permissions = 0

# 1. Grant READ and WRITE permissions
user_permissions = user_permissions | READ_PERMISSION | WRITE_PERMISSION
print(f"After granting R+W: {user_permissions:03b}")  # 110

# 2. Check if user has WRITE permission
has_write = bool(user_permissions & WRITE_PERMISSION)
print(f"Has WRITE? {has_write}")  # True

# 3. Revoke WRITE permission
user_permissions = user_permissions & ~WRITE_PERMISSION
print(f"After revoking W: {user_permissions:03b}")  # 100

# 4. Toggle EXECUTE permission
user_permissions = user_permissions ^ EXECUTE_PERMISSION
print(f"After toggling X: {user_permissions:03b}")  # 101

Summary

  • & (AND) - 1 only if both bits are 1
  • | (OR) - 1 if at least one bit is 1
  • ^ (XOR) - 1 if bits are different
  • ~ (NOT) - Inverts all bits (gives -(n+1))
  • << - Left shift multiplies by 2^n
  • >> - Right shift divides by 2^n
  • Use cases: Permission flags, efficient math, finding unique elements

What's Next?

Now that you understand bitwise operations, let's learn about membership operators (in and not in) - simple but powerful operators for checking if values exist in sequences like lists, strings, and dictionaries.