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.