Bits & Binary
Understand how computers store and manipulate information using binary digits, bitwise operators, and bitmasks.
What is a bit?
A bit (short for binary digit) is the smallest unit of information a computer can store. It has exactly two possible values: 0 or 1. Every file, every number, every pixel on your screen is ultimately a sequence of bits.
Bits are grouped together to represent larger values and more complex data:
| Unit | Size | Approximate real-world size |
|---|---|---|
| 1 bit | 1 bit | A single on/off switch |
| 1 byte | 8 bits | One ASCII character (e.g. A) |
| 1 kilobyte (KB) | 1,024 bytes | A short text message |
| 1 megabyte (MB) | 1,024 KB | A compressed photo |
| 1 gigabyte (GB) | 1,024 MB | About 200 MP3 songs |
| 1 terabyte (TB) | 1,024 GB | About 500 hours of HD video |
Storage manufacturers often use powers of 10 (1 KB = 1,000 bytes) while operating systems use powers of 2 (1 KB = 1,024 bytes). This is why a "500 GB" hard drive shows as ~465 GB in your OS.
Why do computers use binary?
Computers are built from billions of transistors, tiny electronic switches that are either conducting electricity or not. This physical reality maps perfectly to binary: a high voltage represents 1, a low voltage represents 0. Designing circuits that distinguish between just two states is dramatically simpler and more reliable than distinguishing between ten.
This is why all digital information, no matter how complex, is encoded as sequences of 0s and 1s at the hardware level.
The binary number system
In everyday life we use base-10 (decimal): each digit position represents a power of 10. Binary works the same way but in base-2: each position represents a power of 2.
Reading a binary number is straightforward: assign place values from right to left starting at 20 = 1, then add up the positions where a 1 appears.
Worked example: 00101010 in binary
| Bit position | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Place value | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| Bit value | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
Positions with a 1: 32 + 8 + 2 = 42
So 00101010 in binary equals 42 in decimal. The diagram below shows this visually.
Bitwise operators
Bitwise operators work directly on the individual bits of integer values. They are extremely fast — a single CPU instruction — and appear in everything from graphics engines to network protocols.
AND (&)
Sets a result bit to 1 only if both input bits are 1.
0101 (5)
& 0011 (3)
------
0001 (1)
Practical use: permission checks. If READ = 0001 and a user's permission byte is 0101, then perms & READ != 0 tells you the READ bit is set without touching other bits.
OR (|)
Sets a result bit to 1 if either input bit is 1.
0101 (5)
| 0010 (2)
------
0111 (7)
Practical use: granting permissions. perms | WRITE turns on the WRITE bit while leaving all other bits unchanged.
XOR (^)
Sets a result bit to 1 if the input bits are different.
0101 (5)
^ 0011 (3)
------
0110 (6)
Practical use: toggling flags. flags ^ FLAG flips a bit: if it was 1 it becomes 0, and vice versa. XOR is also used in simple checksums and encryption — XORing a value with itself always produces 0.
NOT (~)
Flips every bit.
~ 0101 (5)
------
1010 (-6 in two's complement)
Practical use: clearing bits. perms & ~EXEC clears the EXEC bit: ~EXEC produces a mask with every bit set except EXEC, so ANDing with it zeroes out that one bit.
Left shift (<<) and right shift (>>)
Shifts all bits left or right by a given number of positions. Zeros are shifted in.
0001 << 2 → 0100 (1 becomes 4)
1000 >> 1 → 0100 (8 becomes 4)
Practical use: fast multiplication and division. Left-shifting by n is equivalent to multiplying by 2n. Right-shifting by n is equivalent to dividing by 2n. Compilers often emit shift instructions instead of multiply/divide because they execute in a single cycle.
Bitmasks
A bitmask is an integer value used together with a bitwise operator to isolate, set, or clear specific bits in another integer. Think of it like a stencil: the mask covers the bits you want to leave alone, and exposes only the bits you want to work with.
Checking a bit
perms = 0b00000101 # READ and EXEC set
READ = 0b00000001
is_readable = (perms & READ) != 0 # True
Setting a bit
perms |= WRITE # turns on bit 1 regardless of its current value
Clearing a bit
perms &= ~EXEC # turns off bit 2 regardless of its current value
This three-operation pattern (check, set, clear) appears in Linux file permissions (chmod), TCP flag bytes (SYN, ACK, FIN), network subnet masks, and hardware device registers.
Bitwise permission check in practice
The code example below demonstrates all three operations in a Bash script using Unix-style permission flags:
# Permission flags (bitmask)
READ=1 # 001
WRITE=2 # 010
EXEC=4 # 100
user_perms=5 # 101 — READ + EXEC granted
# Check if WRITE permission is set
if (( (user_perms & WRITE) != 0 )); then
echo "Write permission granted"
else
echo "Write permission denied" # prints this
fi
# Grant WRITE permission
user_perms=$((user_perms | WRITE)) # 101 | 010 = 111
# Revoke EXEC permission
user_perms=$((user_perms & ~EXEC)) # 111 & ~100 = 011
The same pattern appears in PostgreSQL row-level security, JWT scope bytes, and virtually every embedded systems driver you will encounter.
Further Reading
Code Examples
Continue learning
ACID & Isolation Levels
Deep dive into database transaction guarantees, isolation levels, concurrency anomalies like write skew, and control mechanisms such as MVCC, 2PL, and SSI.
API Gateways
Understand the API Gateway pattern as the central ingress point for microservices, handling routing, auth, rate limiting, and protocol translation.
API Security & OAuth 2.0
Understand API authentication and authorization mechanisms, JWT security, and the OAuth 2.0 framework including Authorization Code Flow with PKCE.