Bitwise operations explained
Bitwise operators work on the individual bits of an integer rather than its numeric value. They look low level, but they turn up in everyday code: permission systems, feature flags, color channels, and network masks all lean on them. Once you can picture the bits lined up, each operator does one obvious thing.
The four logical operators
Line two numbers up bit by bit and apply the rule to each column.
- AND (
&) gives 1 only where both bits are 1. Used to test or clear bits. - OR (
|) gives 1 where either bit is 1. Used to set bits. - XOR (
^) gives 1 where the bits differ. Used to toggle bits and to compare. - NOT (
~) flips every bit. Unary; it inverts the whole number.
1100 1100 1100
& 1010 | 1010 ^ 1010
= 1000 = 1110 = 0110
A useful XOR fact: a value XORed with itself is 0, and XORing twice with the same mask returns the original. That is why XOR shows up in toggles and simple checksums.
Shifts
Left shift (<<) moves every bit left and fills with zeros on the right. Right shift (>>) moves them right. Each position is a power of two:
3 << 2 = 12 (0011 -> 1100) same as 3 * 4
12 >> 1 = 6 (1100 -> 0110) same as 12 / 2
Shifting left by n multiplies by 2 to the n, shifting right divides by it. On most hardware a shift is faster than a general multiply or divide, which is why you still see x << 1 for doubling in hot paths. Be careful with right shift on signed numbers: an arithmetic right shift preserves the sign bit, so negative values stay negative.
Masking and flags
The most common real use is packing several on or off settings into one integer. Define each flag as a single bit:
#define READ 1 // 0001
#define WRITE 2 // 0010
#define EXEC 4 // 0100
int perms = READ | WRITE; // set read and write -> 0011
if (perms & WRITE) { ... } // test a flag
perms &= ~WRITE; // clear write -> 0001
perms ^= EXEC; // toggle exec
This is exactly how Unix file permissions work, where read, write, and execute are three bits per user class. The same pattern stores compact option sets in databases and binary protocols: one integer column instead of a dozen booleans. A mask is just a value with the bits you care about set, used with AND to isolate them or with OR to apply them.
A practical check
Permission bits are also why chmod 755 reads the way it does, with each octal digit encoding three permission bits. See understanding chmod and Unix permissions for that mapping in full.
When you want to watch these operations happen, convert the operands to binary first with the base converter, line up the columns, and apply the rule by hand. The conversion runs in your browser, so nothing you type is sent anywhere. Reach for bitwise operators when you need compact flags, fast power of two arithmetic, or to work with the bits of a value directly, and skip the cleverness when a plain boolean or multiply would read more clearly. For the number systems underneath, see converting between binary, hex, and decimal.