TL;DR: Computers think in binary (0s and 1s). Humans think in decimal (0-9). Developers often use hex (0-F) as a shorthand for binary because each hex digit maps to exactly 4 bits. You'll encounter these conversions constantly — CSS colors, file permissions, IP addresses, bitwise flags. The trick: 4 binary digits = 1 hex digit.
You probably learned to count in base 10 because you have 10 fingers. Computers count in base 2 because they have billions of tiny switches that are either on or off. And developers use base 16 because writing FF is way easier than 11111111. Let's learn to speak all four "number languages."
Meet the Four Number Systems
| Base | Name | Digits | Code Prefix | You'll See It In... |
|---|---|---|---|---|
| 2 | Binary | 0, 1 | 0b | Bit manipulation, hardware |
| 8 | Octal | 0-7 | 0o | Unix file permissions |
| 10 | Decimal | 0-9 | (none) | Everything humans read |
| 16 | Hexadecimal | 0-9, A-F | 0x | Colors, memory, byte values |
The number 255 in every language:
Decimal: 255
Binary: 11111111
Octal: 377
Hexadecimal: FF
How Positional Numbers Work (It's Simpler Than You Think)
Every number system works the same way — each digit's position gives it a different "weight." In decimal, you already know this intuitively:
742 = 7 x 100 + 4 x 10 + 2 x 1
= 7 x 10² + 4 x 10¹ + 2 x 10&sup0;
Binary works the exact same way, just with powers of 2:
1011 (binary) = 1x8 + 0x4 + 1x2 + 1x1
= 1x2³ + 0x2² + 1x2¹ + 1x2&sup0;
= 8 + 0 + 2 + 1
= 11 (decimal)
And hex uses powers of 16:
1A3 (hex) = 1x256 + 10x16 + 3x1
= 1x16² + A(10)x16¹ + 3x16&sup0;
= 256 + 160 + 3
= 419 (decimal)
Dev Joke: There are 10 types of people in the world: those who understand binary and those who don't. (And those who didn't expect this joke to be in base 3.)
Decimal to Any Base: The Division Trick
Want to convert a decimal number to any base? Repeatedly divide by the base and read the remainders bottom-to-top:
Convert 156 to Binary
156 / 2 = 78 remainder 0
78 / 2 = 39 remainder 0
39 / 2 = 19 remainder 1
19 / 2 = 9 remainder 1
9 / 2 = 4 remainder 1
4 / 2 = 2 remainder 0
2 / 2 = 1 remainder 0
1 / 2 = 0 remainder 1
Read bottom-to-top: 10011100
Check: 128 + 0 + 0 + 16 + 8 + 4 + 0 + 0 = 156 ✓
The Binary-Hex Shortcut (Memorize This!)
Since 16 = 24, each hex digit maps to exactly 4 binary digits. This makes conversion between binary and hex almost instant — just group bits in fours:
Binary: 1010 1111 0011 1100
Hex: A F 3 C
Result: 0xAF3C
This is THE reason developers love hex — it's 4x more compact than binary while maintaining a perfect bit-level mapping.
Hex-to-Binary Quick Reference:
0=0000 4=0100 8=1000 C=1100
1=0001 5=0101 9=1001 D=1101
2=0010 6=0110 A=1010 E=1110
3=0011 7=0111 B=1011 F=1111
Where You'll Actually Use This
CSS Colors (Hex)
Every CSS hex color is just three bytes — red, green, blue:
#FF6B35
| | |
| | +-- Blue: 0x35 = 53
| +----- Green: 0x6B = 107
+-------- Red: 0xFF = 255
Same as: rgb(255, 107, 53)
Unix File Permissions (Octal)
chmod 755 file.sh
7 = 111 (binary) → rwx (read + write + execute) — owner
5 = 101 (binary) → r-x (read + execute) — group
5 = 101 (binary) → r-x (read + execute) — others
Pro Tip: Octal is perfect for permissions because each digit maps to exactly 3 bits — one for read, one for write, one for execute. It's not arbitrary; it's elegant!
Bitwise Flags (Binary)
// Permission flags using bit positions
const READ = 0b0001; // 1
const WRITE = 0b0010; // 2
const EXECUTE = 0b0100; // 4
const ADMIN = 0b1000; // 8
// Combine with OR
const userPerms = READ | WRITE; // 0b0011 = 3
// Check with AND
const canWrite = (userPerms & WRITE) !== 0; // true
const isAdmin = (userPerms & ADMIN) !== 0; // false
IP Addresses (Binary Under the Hood)
IP: 192.168.1.1
Binary: 11000000.10101000.00000001.00000001
Subnet: 255.255.255.0
Binary: 11111111.11111111.11111111.00000000
^^^^ Host portion
Base Conversion in Code
JavaScript
const num = 255;
// Decimal → other bases
num.toString(2); // "11111111" (binary)
num.toString(8); // "377" (octal)
num.toString(16); // "ff" (hex)
// Other bases → decimal
parseInt('11111111', 2); // 255
parseInt('377', 8); // 255
parseInt('ff', 16); // 255
// Number literals
const binary = 0b11111111; // 255
const octal = 0o377; // 255
const hex = 0xFF; // 255
Python
num = 255
bin(num) # '0b11111111'
oct(num) # '0o377'
hex(num) # '0xff'
int('11111111', 2) # 255
int('377', 8) # 255
int('ff', 16) # 255
# Formatted output
f'{num:08b}' # '11111111' (zero-padded binary)
f'{num:02X}' # 'FF' (uppercase hex)
The Leading Zero Trap
Watch Out: In some languages, a leading zero means octal, not decimal! In JavaScript, parseInt('010') can return 8 (octal) in some engines. Always specify the radix: parseInt('010', 10) to get 10. Python 3 made this a SyntaxError to prevent confusion.
Two's Complement: Negative Numbers in Binary
Ever wonder how computers represent negative numbers with just 0s and 1s? They use two's complement: flip all the bits and add 1.
5 = 00000101
-5 = ?
Step 1: Flip bits → 11111010
Step 2: Add 1 → 11111011 = -5
This is why signed 8-bit integers range from -128 to 127:
01111111 = 127 (max positive)
10000000 = -128 (min negative)
11111111 = -1 (all 1s = -1, not 255!)
This also explains integer overflow — when 127 + 1 becomes -128 in a signed byte. It's not a bug; it's two's complement wrapping around.
Wrapping Up
Number base conversion isn't just a CS class exercise — it's a practical skill you'll use constantly. CSS colors, file permissions, network masks, bitwise flags, memory debugging — it all comes down to understanding how bases work. The key insight? They all use the same positional logic; only the base changes. And once you memorize that 4 bits = 1 hex digit, most conversions become quick mental math.
Try It Yourself
Convert between binary, octal, decimal, and hexadecimal instantly — type a number in any base and see all others update in real time.
Open Number Base Converter →