Skip to content

Instantly share code, notes, and snippets.

@KyleWMiller
Created November 13, 2025 17:19
Show Gist options
  • Select an option

  • Save KyleWMiller/7f4d28c73331a653c2144a3c5ce423ad to your computer and use it in GitHub Desktop.

Select an option

Save KyleWMiller/7f4d28c73331a653c2144a3c5ce423ad to your computer and use it in GitHub Desktop.

C++ Bitwise Operations Cheatsheet

Basic Bitwise Operators

Operator Name Plain English Example Result
& AND "Both bits must be ON" 5 & 3
0101 & 0011
0001 (1)
| OR "At least one bit must be ON" 5 | 3
0101 | 0011
0111 (7)
^ XOR "Bits must be different" 5 ^ 3
0101 ^ 0011
0110 (6)
~ NOT "Flip all bits" ~5
~00000101
11111010 (-6)*
<< Left Shift "Move bits left, fill with zeros" 5 << 2
0101 << 2
10100 (20)
>> Right Shift "Move bits right, fill with zeros†" 20 >> 2
10100 >> 2
00101 (5)

*For signed 8-bit integer
†For unsigned integers; signed integers may fill with sign bit

Compound Assignment Operators

Operator Equivalent To Plain English
a &= b a = a & b "Keep only bits that are ON in both"
a |= b a = a | b "Turn ON all bits from b"
a ^= b a = a ^ b "Toggle bits that are ON in b"
a <<= n a = a << n "Multiply by 2^n"
a >>= n a = a >> n "Divide by 2^n"

Visual Bit-by-Bit Operations

AND (&) - "Do both have it?"

  1010
& 1100
------
  1000  → Only where BOTH are 1

OR (|) - "Does either have it?"

  1010
| 1100
------
  1110  → Where EITHER is 1

XOR (^) - "Are they different?"

  1010
^ 1100
------
  0110  → Only where bits DIFFER

NOT (~) - "Flip everything"

~ 1010
------
  0101  → All bits INVERTED

Common Bit Patterns & Masks

Pattern Code Plain English Use Case
Set bit n num |= (1 << n) "Turn ON bit at position n" Enable feature/permission
Clear bit n num &= ~(1 << n) "Turn OFF bit at position n" Disable feature/permission
Toggle bit n num ^= (1 << n) "Flip bit at position n" Switch state
Check bit n num & (1 << n) "Is bit n ON?" Test flag/permission
Clear all bits num = 0 "Turn OFF everything" Reset
Set all bits num = ~0 "Turn ON everything" Initialize to all 1s
Get rightmost bit num & -num "Isolate lowest ON bit" Find first set flag
Clear rightmost bit num & (num - 1) "Turn OFF lowest ON bit" Remove flags one by one

Arithmetic Using Bitwise Operations

Operation Bitwise Method Plain English Note
Multiply by 2^n x << n "Shift left by n" Much faster than x * pow(2,n)
Divide by 2^n x >> n "Shift right by n" Integer division for positive numbers
Multiply by 2 x << 1 "Move all bits left once"
Divide by 2 x >> 1 "Move all bits right once"
Check if even (x & 1) == 0 "Is the last bit OFF?" Even numbers have 0 in bit 0
Check if odd (x & 1) == 1 "Is the last bit ON?" Odd numbers have 1 in bit 0
Get modulo 2^n x & ((1 << n) - 1) "Keep only the last n bits" Works when divisor is power of 2

Useful Bit Manipulation Tricks

Operation Code Plain English Example
Check power of 2 n > 0 && (n & (n-1)) == 0 "Is only one bit ON?" 8 (1000) → true
Count set bits __builtin_popcount(n) "How many bits are ON?" 5 (0101) → 2
Swap values a ^= b; b ^= a; a ^= b; "XOR swap without temp variable" No extra memory needed
Get absolute value (n ^ (n >> 31)) - (n >> 31) "Flip sign if negative" For 32-bit integers
Find min b ^ ((a ^ b) & -(a < b)) "Choose smaller without branching" Branchless programming
Find max a ^ ((a ^ b) & -(a < b)) "Choose larger without branching" Branchless programming
Toggle case c ^ 32 "Switch uppercase/lowercase" ASCII letters only
Round up to power of 2 See below* "Find next highest power of 2" 2532

*Round up to power of 2:

n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;

Flag Management Pattern

// Define flags using left shift
const uint8_t FLAG_READ    = 1 << 0;  // 0001
const uint8_t FLAG_WRITE   = 1 << 1;  // 0010
const uint8_t FLAG_EXECUTE = 1 << 2;  // 0100
const uint8_t FLAG_DELETE  = 1 << 3;  // 1000

uint8_t permissions = 0;

// Operations - Plain English
permissions |= FLAG_READ;           // "Grant READ permission"
permissions |= (FLAG_READ | FLAG_WRITE);  // "Grant READ and WRITE"
permissions &= ~FLAG_WRITE;          // "Revoke WRITE permission"
permissions ^= FLAG_EXECUTE;         // "Toggle EXECUTE permission"

if (permissions & FLAG_READ)        // "Can they READ?"
if (permissions & (FLAG_READ | FLAG_WRITE))  // "Can they READ or WRITE?"
if ((permissions & FLAG_WRITE) && (permissions & FLAG_EXECUTE))  // "Can they WRITE and EXECUTE?"

RGB Color Manipulation

// Pack/Unpack colors - Plain English
uint32_t color = (r << 16) | (g << 8) | b;    // "Combine R, G, B into one number"
uint8_t red   = (color >> 16) & 0xFF;          // "Extract red component"
uint8_t green = (color >> 8) & 0xFF;           // "Extract green component"
uint8_t blue  = color & 0xFF;                  // "Extract blue component"

// Manipulate colors
color &= 0xFF00FF;                             // "Remove green channel"
color |= (128 << 8);                           // "Set green to 128"
color ^= 0xFFFFFF;                            // "Invert all colors"

Subset/Combination Generation

// Iterate through all subsets - Plain English
for (int subset = 0; subset < (1 << n); subset++) {
    // Each bit position represents include/exclude for element
    // "Try all possible combinations"
}

// Iterate through all subsets of a set
int set = 0b1101;  // Original set
for (int subset = set; subset > 0; subset = (subset - 1) & set) {
    // "Visit each valid subset"
}

Network/Systems Programming

// IP Address operations - Plain English
uint32_t ip = (192 << 24) | (168 << 16) | (1 << 8) | 100;  // "Pack IP: 192.168.1.100"
uint8_t first_octet = (ip >> 24) & 0xFF;                    // "Extract first byte"

// Subnet mask operations
uint32_t subnet_mask = ~((1 << (32 - prefix_length)) - 1);  // "Create subnet mask"
uint32_t network = ip & subnet_mask;                         // "Get network address"
bool same_network = (ip1 & mask) == (ip2 & mask);           // "Are they on same network?"

// Endianness conversion
uint16_t big_endian = ((little << 8) | (little >> 8));      // "Swap byte order"

Performance Guidelines

When to Use Bitwise Operations

DO USE for:

  • Flag/permission systems
  • Embedded systems & hardware control
  • Graphics programming (colors, pixels)
  • Network protocols
  • Hash functions
  • Cryptography
  • When every CPU cycle matters

DON'T USE for:

  • Regular arithmetic (compiler optimizes x * 8x << 3)
  • Premature optimization
  • When readability is more important than nano-optimization

Type Safety Tips

// GOOD: Use unsigned types for bit manipulation
uint32_t flags = 0;
flags |= (1U << 15);  // Safe

// BAD: Signed types can cause undefined behavior
int flags = 0;
flags |= (1 << 31);   // Undefined behavior!

// GOOD: Use fixed-width types for portability
uint32_t mask = 0xFF00FF00;  // Always 32 bits

// BAD: int size varies by platform
unsigned int mask = 0xFF00FF00;  // Could be 16, 32, or 64 bits

Quick Reference - What Each Operation Does to Numbers

Operation Effect on Number Example
n << 1 Multiply by 2 5 << 1 = 10
n >> 1 Divide by 2 10 >> 1 = 5
n & (n-1) Remove lowest set bit 12 & 11 = 8 (1100 & 1011 = 1000)
n & -n Isolate lowest set bit 12 & -12 = 4 (1100 & ...10100 = 0100)
n | (n+1) Set lowest unset bit 10 | 11 = 11 (1010 | 1011 = 1011)
n ^ (n+1) Get mask of trailing zeros + 1 8 ^ 9 = 1 (1000 ^ 1001 = 0001)

Memory Alignment & Structure Packing

// Check alignment - Plain English
bool is_aligned = (address & (alignment - 1)) == 0;  // "Is address aligned to boundary?"

// Round up to alignment
size_t aligned = (size + align - 1) & ~(align - 1);   // "Round up to next alignment"

// Extract bit fields
struct Packet {
    uint16_t data;
    // Extract fields using masks and shifts
    uint8_t getType()  { return (data >> 12) & 0x0F; }  // "Get bits 12-15"
    uint8_t getFlags() { return (data >> 8) & 0x0F; }   // "Get bits 8-11"
    uint8_t getValue() { return data & 0xFF; }          // "Get bits 0-7"
};

Remember: Bitwise operations work on the binary representation of numbers. Think of each number as a row of switches (bits) that can be ON (1) or OFF (0). These operations let you manipulate those switches directly and efficiently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment