Single Bit Operations Cheatsheet for C Programmers
Note: This post was originally written in 2015 and has been lightly refreshed for clarity. The content and examples are unchanged — just the presentation got a coat of paint.
There are things in C that I use often enough to need them, but infrequently enough to always forget the exact syntax. Bit manipulation is one of them. Not the concept — that part sticks — but the precise one-liner when you’re three levels deep into a register driver at 11pm and your brain refuses to reconstruct it from first principles.
So I wrote this down once. Then I wrote it down again on a different machine. Then again in a notebook. At some point I figured: just put it somewhere permanent.
This is that somewhere. A no-frills cheatsheet for C and embedded programmers. Bookmark it, copy it into your notes, tattoo it on your forearm — whatever works.
The operations
Set a bit
Use the bitwise OR operator (|) to set bit x:
number |= 1 << x;
You’re ORing with a mask that has only bit x set. Everything else stays untouched.
Clear a bit
Use the bitwise AND operator (&) combined with NOT (~) to clear bit x:
number &= ~(1 << x);
The ~(1 << x) produces a mask with all bits set except bit x. ANDing with it forces
that bit to 0 while leaving everything else alone.
Toggle a bit
The XOR operator (^) flips a bit — 0 becomes 1, 1 becomes 0:
number ^= 1 << x;
Useful when you want to blink an LED or flip a flag without checking its current state first.
Check a bit
Shift right by x, then AND with 1 to isolate it:
bit = (number >> x) & 1;
The result is either 0 or 1 — the value of bit x.
Set the n-th bit to a specific value
Sometimes you want to force a bit to a known value (0 or 1) rather than just toggling:
number ^= (-x ^ number) & (1 << n);
Bit n will be set if x is 1, and cleared if x is 0. The trick works because
-1 in two’s complement is all-ones (0xFF...FF), and -0 is zero — so -x becomes
the mask you need.
Why this matters in embedded
When you’re working directly with hardware registers — GPIO, timers, UART control registers —
bitwise operations are how you talk to the hardware. You don’t write reg = 5, you set
individual control bits without disturbing the others. Getting these wrong means the peripheral
misbehaves in ways that are annoying to debug.
The patterns above cover ~95% of what you’ll actually need. The remaining 5% is usually multi-bit fields, which are just combinations of the same primitives with wider masks.
That’s it. Short and to the point — the way a cheatsheet should be.