Bitwise Operators & Flags

Manipulate individual bits with & | ^ ~ << >> — and model permission flags cleanly.

Bitwise operators work on the binary representation of integers, one bit at a time.

OperatorNameExample
&AND (both 1)0b1100 & 0b1010 = 0b1000
|OR (either 1)0b1100 | 0b1010 = 0b1110
^XOR (differ)0b1100 ^ 0b1010 = 0b0110
~NOT (invert)~5 = -6
<<shift left1 << 4 = 16
>>shift right16 >> 2 = 4
flags = 0b0000
flags |= 0b0010     # set a bit
print(bin(flags))   # 0b10
print(flags & 0b0010)   # 2  -> the bit is on
flags &= ~0b0010    # clear that bit
print(bin(flags))   # 0b0

You rarely write raw bits

In modern Python, enum.IntFlag gives you named, combinable flags with all the readability of an enum and all the speed of bitwise maths. That is almost always the right tool — the raw operators below are what it is built on.

Example

Example · python
from enum import IntFlag, auto

class Permission(IntFlag):
    READ    = auto()   # 1
    WRITE   = auto()   # 2
    EXECUTE = auto()   # 4
    ALL     = READ | WRITE | EXECUTE

# Combine with | , test with & , remove with & ~
role = Permission.READ | Permission.WRITE
print('role          :', role)                       # Permission.READ|WRITE
print('can write?    :', Permission.WRITE in role)    # True
print('can execute?  :', Permission.EXECUTE in role)  # False

role |= Permission.EXECUTE          # grant execute
role &= ~Permission.WRITE           # revoke write
print('after changes :', role)                        # READ|EXECUTE
print('is ALL?       :', role == Permission.ALL)      # False
print('raw value     :', int(role))                   # 5

# Output:
# role          : Permission.READ|WRITE
# can write?    : True
# can execute?  : False
# after changes : Permission.READ|EXECUTE
# is ALL?       : False
# raw value     : 5

When to use it

  • A permission system stores read/write/execute flags as bits in an integer and checks them with &.
  • A network library extracts the high and low bytes of a 16-bit port number using bit-shifts and masks.
  • A game engine uses XOR (^) to toggle a feature flag bit without needing an explicit if statement.

More examples

Bitwise AND, OR, XOR

Shows AND, OR, and XOR in binary notation so the bit-level effect is visible.

Example · python
a = 0b1010   # 10
b = 0b1100   # 12
print(bin(a & b))   # 0b1000  (AND: both bits set)
print(bin(a | b))   # 0b1110  (OR: either bit set)
print(bin(a ^ b))   # 0b0110  (XOR: exactly one set)

Permission flags with bitmasks

Models Unix-style permission flags as bit fields using OR to set and AND to query them.

Example · python
READ    = 0b001   # 1
WRITE   = 0b010   # 2
EXECUTE = 0b100   # 4

user_perms = READ | WRITE    # 3
print(bool(user_perms & READ))     # True
print(bool(user_perms & EXECUTE))  # False
user_perms |= EXECUTE               # grant execute
print(bin(user_perms))             # 0b111

Left and right bit-shifts

Shows left/right shifts as fast powers-of-two scaling and uses them to split a word into bytes.

Example · python
x = 1
print(x << 4)    # 16  (multiply by 2^4)
print(256 >> 3)  # 32  (divide by 2^3)

# Extract high/low bytes of a 16-bit value:
value = 0xABCD
high = (value >> 8) & 0xFF
low  = value & 0xFF
print(hex(high), hex(low))   # 0xab 0xcd

Discussion

  • Be the first to comment on this lesson.