Bitwise operations allow direct manipulation of individual bits within integer types. While high-level abstractions simplify development, C++ retains low-level control—enabling performance-critical optimizations, compact data encoding, and hardware-adjacent logic without resorting to assembly.
Operator Precedence Overview
| Precedence Level | Operators |
|---|---|
| 1 | Parentheses: () |
| 2 | Unary: !, ~, ++, --, * (dereference), & (address) |
| 3 | Multiplicative: *, /, % |
| 4 | Additive: +, - |
| 5 | Bit shifts: <<, >> |
| 6 | Reltaional: <, <=, >, >= |
| 7 | Equality: ==, != |
| 8 | Bitwise AND: & |
| 9 | Bitwise XOR: ^ |
| 10 | Bitwise OR: | |
| 11 | Logical AND: && |
| 12 | Logical OR: || |
| 13 | Conditional: ?: |
| 14 | Assignment: =, +=, -=, *=, /=, etc. |
| 15 | Comma: , |
Core Bit Manipulation Patterns
Extract the j-th Bit (0-indexed from LSB)
To read bit j of a integer value, right-shift by j positions and mask with 1:
bool bit_j = (value >> j) & 1;
Modify a Specific Bit
Set bit j to 1
int updated = value | (1U << j);
Clear bit j to 0
Use bitwise AND with a mask that has all bits set except position j:
int updated = value & ~(1U << j);
Flip bit j
int updated = value ^ (1U << j);
Clear the Least Significant Set Bit
This idiom removes the rightmost 1 in the binary representation:
int cleared = value & (value - 1);
Example: 12 (1100₂) → 8 (1000₂).
Isolate the Least Significant Set Bit
The expression value & -value yields an integer with only the lowest set bit preserved. This works because two’s complement negation flips all bits and adds one, causing carry propagation up to and including the first 1:
int lsb_only = value & static_cast<unsigned int>(-static_cast<int>(value));
For unsigned inputs, simpler form suffices:
unsigned int lsb_only = value & -value;