Bitwise Operators
Working with single bitsEvery number is stored as bits, and C lets you work with those bits directly. Bitwise operators combine numbers
bit by bit, and shifts move all the bits left or right. In the lab below you watch every bit column being worked out,
use one byte as 8 on/off switches, and see why << multiplies by 2.
- 12 & 10is 8 — but 12 && 10 is 1
- x << 1doubles x
- f |= 1 << nswitches bit n on
Ready
Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode
The ideas behind the lab
Exactly what you watched happen, in plain steps.
Operators that work on bits
Bitwise operators treat a number as a row of bits and work on each bit position separately. They are used for flags (many yes/no settings in one number), hardware registers, colours, compression and fast arithmetic with powers of 2. They work only with whole numbers.
a = 12 → 0000 1100 b = 10 → 0000 1010 a & b = 8 → 0000 1000 both 1 a | b = 14 → 0000 1110 either 1 a ^ b = 6 → 0000 0110 different ~a → every bit flipped a << 1 = 24 → 0001 1000 × 2 a >> 1 = 6 → 0000 0110 ÷ 2
| Operator | Name | Rule for each bit | Example | Result |
|---|---|---|---|---|
| & | AND | 1 only if both bits are 1 | a & b | 8 |
| | | OR | 1 if at least one bit is 1 | a | b | 14 |
| ^ | XOR (exclusive or) | 1 if the bits are different | a ^ b | 6 |
| ~ | NOT (complement) | flips every bit | ~a | -13 (as an int) |
| << | left shift | moves bits left, 0s come in | a << 2 | 48 |
| >> | right shift | moves bits right, bits fall off | a >> 2 | 3 |
| &= |= ^= <<= >>= | compound forms | a op= b means a = a op b | a |= 1 | 13 |
AND, OR, XOR, NOT
- Line the two numbers up in binary and work on each column separately.
- & gives 1 only where both have a 1 — use it to TEST or CLEAR bits.
- | gives 1 where either has a 1 — use it to SET bits.
- ^ gives 1 where the bits differ — use it to TOGGLE bits. x ^ x is 0.
- ~ flips every bit; for an int, ~x equals −x − 1.
Shifts
- x << n moves every bit n places left: the same as x × 2ⁿ (if nothing overflows).
- x >> n moves every bit n places right: the same as x ÷ 2ⁿ, rounded down, for positive x.
- 1 << n is a number with only bit n switched on (2ⁿ).
- Shifting a negative number right is decided by the compiler (gcc copies the sign bit).
- Shifting by a negative amount or by the width of the type (32 for int) is undefined.
Masks: one byte, 8 switches
- Number the bits from 0 (rightmost) to 7 (leftmost).
- Set bit n: f |= (1 << n);
- Clear bit n: f &= ~(1 << n);
- Toggle bit n: f ^= (1 << n);
- Test bit n: (f >> n) & 1 — gives 1 or 0.
Settings stored in one byte
Every line, explained.
#include <stdio.h>
#define BOLD (1 << 0)
Bit 0 means "bold" (value 1).
#define ITALIC (1 << 1)
Bit 1 means "italic" (value 2).
#define UNDERLINE (1 << 2)
Bit 2 means "underline" (value 4).
int main(void)
{
unsigned char style = 0;
All switches off: 0000 0000.
style |= BOLD | UNDERLINE;
Switch two bits on at once: 0000 0101 = 5.
style ^= ITALIC;
Toggle italic: 0000 0111 = 7.
style &= ~BOLD;
Switch bold off: 0000 0110 = 6.
printf("%d\n", style);
Prints 6
printf("%d\n", (style & ITALIC) != 0);
Test a bit: italic is on → 1
printf("%d\n", 5 << 3);
5 × 2³ = 40
return 0;
}
Spot the bug
Mistakes almost every beginner makes — and how to fix them.
& and | instead of && and ||
if (1 & 2) // false!
if (1 && 2) // true
1 & 2 compares bits: 01 & 10 = 00, so 0. && is the logical AND you need in conditions.
^ is not "to the power of"
int square = x ^ 2;
int square = x * x;
^ is XOR. 5 ^ 2 is 7, not 25. Use x * x, or pow() from math.h for doubles.
Forgetting parentheses
if (flags & MASK == MASK)
if ((flags & MASK) == MASK)
== binds tighter than &, so the first means flags & (MASK == MASK), which is flags & 1.
Clearing a bit with ~ in the wrong place
f = ~f & (1 << 3);
f = f & ~(1 << 3);
The ~ belongs to the MASK, not to f: ~(1 << 3) is all 1s except bit 3.
Shifting too far
int big = 1 << 32;
long long big = 1LL << 32;
An int has 32 bits, so shifting it by 32 or more is undefined. Use a 64-bit type for bigger shifts.
Check your understanding
Answer each question — you will see the explanation straight away.
What is 6 & 3 ?
0110 & 0011 = 0010 = 2.
What is 6 | 3 ?
0110 | 0011 = 0111 = 7.
What is 6 ^ 3 ?
0110 ^ 0011 = 0101 = 5. ^ is XOR, not a power.
What is 5 << 2 ?
Shifting left by 2 multiplies by 4: 5 × 4 = 20.
Which statement switches bit 4 of f ON?
OR with a mask that has only bit 4 set switches that bit on and keeps the others.
Bitwise Operators quiz
Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.