The core idioms
x & (1 << i) // test bit i (non-zero if set)
x >> i & 1 // test bit i (gives 0 or 1)
x | (1 << i) // set bit i
x & ~(1 << i) // clear bit i
x ^ (1 << i) // toggle bit i
x & (x - 1) // clear the lowest set bit
x & (-x) // isolate the lowest set bit (== x & (~x + 1))
x | (x + 1) // set the lowest clear bit
x & (x + 1) // clear all trailing ones
~x & (x + 1) // isolate the lowest clear bit
x == (x & -x) // is x a power of two? (plus x != 0)
(x & (x - 1)) == 0 // same testShift pitfalls
1 << iis anint. For this is undefined behaviour — write1LL << i.- Shifting by the type’s width is undefined, not zero.
-xon the minimum value of a signed type is undefined; use unsigned for bit twiddling.
Builtin functions
__builtin_popcount(x) // number of set bits (ll: __builtin_popcountll)
__builtin_clz(x) // count leading zeros — UNDEFINED for x == 0
__builtin_ctz(x) // count trailing zeros — UNDEFINED for x == 0
__builtin_parity(x) // popcount & 1
__lg(x) // floor(log2(x)) = 31 - clz(x)C++20 offers portable equivalents in <bit>: popcount, countl_zero, countr_zero, bit_width, bit_ceil, has_single_bit, rotl, rotr. See Builtin Bit Functions.
Derived quantities
| Want | Expression |
|---|---|
31 - __builtin_clz(x) or __lg(x) | |
| Highest power of 2 | 1 << __lg(x) |
| Smallest power of 2 | x <= 1 ? 1 : 1 << (__lg(x-1) + 1) |
| Is a power of 2 | x && !(x & (x-1)) |
| Round down to a multiple of | x & ~((1<<k)-1) |
| Round up to a multiple of | (x + (1<<k) - 1) & ~((1<<k)-1) |
| Swap without a temporary | a ^= b; b ^= a; a ^= b; (fails if &a == &b) |
| Absolute value, branchless | (x ^ (x>>31)) - (x>>31) |
| Min, branchless | b ^ ((a ^ b) & -(a < b)) |
| Sign | (x > 0) - (x < 0) |
The branchless forms are curiosities on modern CPUs — the compiler generates cmov from the obvious code. Write the readable version.
Set semantics
Treating an integer as a set over :
| Set operation | Bit operation |
|---|---|
| Union | a | b |
| Intersection | a & b |
| Difference | a & ~b |
| Symmetric difference | a ^ b |
| Complement | ~a & ((1<<n)-1) |
| Is ? | (a & b) == a |
| Are disjoint? | (a & b) == 0 |
__builtin_popcount(a) | |
| Add element | a | (1<<i) |
| Remove element | a & ~(1<<i) |
| Full set | (1<<n) - 1 |
See Set Theory.
Iterating
// over the set bits of x
for (int t = x; t; t &= t - 1) {
int i = __builtin_ctz(t);
// ...
}
// over all submasks of mask (including 0)
for (int s = mask; ; s = (s - 1) & mask) {
// ...
if (s == 0) break;
}
// over all supermasks of mask within n bits
for (int s = mask; s < (1 << n); s = (s + 1) | mask) { /* ... */ }The submask loop is summed over all masks — see Enumerating Submasks.
XOR facts worth memorising
| Fact | |
|---|---|
| , | self-inverse |
| XOR is associative and commutative | order does not matter |
| undo by repeating | |
| has period 4 in | |
| XOR is addition without carries | |
| Find the single non-repeating element | XOR everything |
The prefix-XOR period-4 identity computes in , which is the standard trick for XOR-range problems.
See also: General · Builtin Functions · Bitset Optimization