Binary, Octal, Decimal, Hex: The Number Base Cheat Sheet Every Developer Needs

posted 5 min read

If you've ever read a hex colour in CSS, debugged a bitwise operation, or stared at a Linux file permission like chmod 755, you've worked with number bases — whether you realised it or not.

This guide covers the four bases every developer encounters, when each one shows up, and how to convert between them without breaking a sweat.

Why Do Different Number Bases Exist?

Computers store everything as binary (base-2). Humans prefer decimal (base-10). Hexadecimal and octal exist as convenient bridges — they're easy for humans to read while being trivially convertible to and from binary.

The key insight: hex is just a shorthand for binary. Every hex digit maps exactly to 4 binary digits. Every octal digit maps to 3 binary digits. No fuzzy conversion required.

Base 10 — Decimal (what you already know)

Digits: 0–9. Position represents a power of 10.

``

1,234 = (1 × 10³) + (2 × 10²) + (3 × 10¹) + (4 × 10⁰)

= 1000 + 200 + 30 + 4

`

You've used this your entire life. Nothing special here. The reason decimal isn't universal in computing is that it requires more hardware to implement than binary.

Base 2 — Binary (how computers actually store data)

Digits: 0 and 1. Position represents a power of 2.

<code> <p>1010 (binary) = (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)</p> <p>= 8 + 0 + 2 + 0</p> <p>= 10 (decimal)</p> </code>

Where you'll see binary:

  • Bit flags and permissions: chmod 755rwxr-xr-x111 101 101 in binary
  • Bitwise operations in JavaScript: 5 & 3101 & 011 = 0011
  • Memory addresses and hardware registers
  • Network subnet masks: 255.255.255.011111111.11111111.11111111.00000000

Binary in JavaScript:

`javascript
// Write binary literals with 0b prefix (ES2015+)


const flags = 0b1010; // 10 in decimal

// Convert decimal to binary

(10).toString(2); // "1010"

// Convert binary string to decimal

parseInt("1010", 2); // 10

// Bitwise AND to check a flag

const READ_FLAG = 0b0001;

const WRITE_FLAG = 0b0010;

const userPerms = 0b0011;

if (userPerms & READ_FLAG) console.log("Can read");

if (userPerms & WRITE_FLAG) console.log("Can write");

`

Base 16 — Hexadecimal (the developer's best friend)

Digits: 0–9 and A–F (where A=10, B=11, C=12, D=13, E=14, F=15). Position represents a power of 16.

<code> <p>FF (hex) = (15 × 16¹) + (15 × 16⁰)</p> <p>= 240 + 15</p> <p>= 255 (decimal)</p> </code>

The hex-to-binary shortcut: Each hex digit maps to exactly 4 binary digits. Memorise this table once and you'll never struggle with the conversion again:

| Hex | Binary | Decimal |

|-----|--------|---------|

| 0 | 0000 | 0 |

| 1 | 0001 | 1 |

| 4 | 0100 | 4 |

| 8 | 1000 | 8 |

| A | 1010 | 10 |

| F | 1111 | 15 |

So #FF5733 (an orange-red colour in CSS) expands to:

  • FF → 11111111 (red channel: 255)
  • 57 → 01010111 (green channel: 87)
  • 33 → 00110011 (blue channel: 51)

Where you'll see hex:

  • CSS colours: #2f855a, #rgba(0,0,0,0.5)
  • Memory addresses: 0x7fff5fbff990
  • Character codes: é (é in Unicode)
  • SHA/MD5 hashes: 5eb63bbbe01eeed093cb22bb8f5acdc3
  • Colour values in image data
  • Network MAC addresses: 00:1B:44:11:3A:B7

Hex in JavaScript:

`javascript
// Write hex literals with 0x prefix


const MAX_BYTE = 0xFF; // 255

// Convert decimal to hex

(255).toString(16); // "ff"

(255).toString(16).toUpperCase(); // "FF"

// Convert hex string to decimal

parseInt("FF", 16); // 255

parseInt("2f855a", 16); // 3113306

// CSS colour manipulation

function hexToRgb(hex) {

const r = parseInt(hex.slice(1, 3), 16);

const g = parseInt(hex.slice(3, 5), 16);

const b = parseInt(hex.slice(5, 7), 16);

return { r, g, b };

}

hexToRgb('#2f855a'); // { r: 47, g: 133, b: 90 }

`

Base 8 — Octal (mainly for Unix permissions)

Digits: 0–7. Position represents a power of 8.

<code> <p>755 (octal) = (7 × 8²) + (5 × 8¹) + (5 × 8⁰)</p> <p>= 448 + 40 + 5</p> <p>= 493 (decimal)</p> </code>

The octal-to-binary shortcut: Each octal digit maps to exactly 3 binary digits.

| Octal | Binary |

|-------|--------|

| 0 | 000 |

| 7 | 111 |

| 5 | 101 |

| 4 | 100 |

So 755 in octal → 111 101 101 in binary → rwxr-xr-x (owner: read/write/execute, group: read/execute, world: read/execute).

Where you'll see octal:

  • Unix file permissions: chmod 644 file.txt (owner: rw, group/world: r only)
  • Legacy JavaScript string escapes: "\141" = "a" (avoid in modern code)
  • Some network protocol specifications
  • Older assembly and embedded systems code

Octal in JavaScript:

`javascript
// Modern: use 0o prefix (ES2015+)


const perms = 0o755;

// Older code used leading zero — this is confusing, avoid it:

// const perms = 0755; // deprecated! Strict mode throws an error

// Convert decimal to octal

(493).toString(8); // "755"

// Convert octal string to decimal

parseInt("755", 8); // 493

`

Converting Between Bases — Quick Reference

| From \ To | Binary | Octal | Decimal | Hex |

|-----------|---------|---------------|---------------|--------------|

| Binary | — | Group by 3 | Work it out | Group by 4 |

| Octal | Split to 3 binary each | — | Work it out | → Binary → Group by 4 |

| Decimal | Divide by 2 repeatedly | Divide by 8 | — | Divide by 16 |

| Hex | Split to 4 binary each | → Binary → Group by 3 | Work it out | — |

The "group by 4" and "group by 3" conversions are the fast path. For example:

  • 5A (hex) → 0101 1010 (binary) → 01 011 010132 (octal) — no arithmetic needed

Practical Conversions in Code

`javascript
// The universal approach: go through decimal


const num = 255; // decimal starting point

num.toString(2); // "11111111" (binary)

num.toString(8); // "377" (octal)

num.toString(10); // "255" (decimal — same)

num.toString(16); // "ff" (hex)

// Going the other way

parseInt("11111111", 2); // 255

parseInt("377", 8); // 255

parseInt("ff", 16); // 255

`

One function to rule them all:

`javascript
function convertBase(value, fromBase, toBase) {


return parseInt(value, fromBase).toString(toBase);


}

convertBase("ff", 16, 2); // "11111111" (hex to binary)

convertBase("755", 8, 16); // "1ed" (octal to hex)

convertBase("1010", 2, 10); // "10" (binary to decimal)

`

Tricky Edge Cases

Leading zeros in binary: 00001111 and 1111 are both 15. Leading zeros are cosmetic — add them when aligning bits for readability.

Large numbers: JavaScript's built-in parseInt and toString work up to 32-bit integers safely. Beyond that, use BigInt:

<code>javascript <p>BigInt("0x" + "ff".repeat(8)).toString(10); // handles 64-bit hex values</p> </code>

Signed vs unsigned: Be careful with bitwise operations in JavaScript — they operate on 32-bit signed integers. 0xFFFFFFFF >>> 0 gives 4294967295 (unsigned), but 0xFFFFFFFF | 0 gives -1` (signed).

Quick Reference — When To Use Each Base

| Base | Best for |

|------|----------|

| Decimal | Human-readable numbers, API responses, user-facing values |

| Hex | Colours, memory addresses, hashes, binary data representation |

| Binary | Bit flags, bitwise ops, understanding hardware specs |

| Octal | Unix file permissions (that's about it in modern code) |


For quick conversions between all four bases at once — without any JavaScript — the SnappyTools Number Base Converter handles binary, octal, decimal, and hex in a single page. Type in any field and all others update live. Free, no sign-up, runs in your browser.

Originally published at https://snappytools.app/number-base-converter/

More Posts

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolioverified - Apr 1

Just completed another large-scale WordPress migration — and the client left this

saqib_devmorph - Apr 7

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

5 Web Dev Pitfalls That Are Silently Killing Your Projects (With Real Fixes)

Dharanidharan - Mar 3
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

2 comments
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!