Skip to content
← All Tools
🔒All processing in your browser 🚫No uploads stored 🛡️Privacy-first conversion tools No login required
Guide

Number Systems Explained: Binary, Octal, Decimal, and Hex

Bill Crawford — Developer Guide — 2026  ·  Last updated December 14, 2025

When you write 0xFF in code, you're using hexadecimal. When you run chmod 755, you're using octal. When you look at memory addresses or bit flags, you're dealing with binary represented as hex. Understanding number bases isn't just academic — it unlocks large parts of systems programming, networking, and hardware interfacing.

Connect on LinkedIn →

Convert between bases instantly: Our Number Base Converter converts decimal, hex, binary, and octal — type in any field and all others update in real time.

Open Number Base Converter →

Table of Contents

  1. Why Computers Use Binary
  2. How Each Base Works
  3. Binary (Base 2)
  4. Hexadecimal (Base 16)
  5. Octal (Base 8)
  6. Language Prefixes
  7. Bitwise Operations in Practice
  8. Two's Complement: How Computers Store Negative Numbers

Why Computers Use Binary

At the hardware level, computers store information as electrical states: high voltage (1) or low voltage (0). There's no physical way to represent "3" or "7" in a single transistor — only on or off. Binary (base 2) maps directly to this physical reality: every bit is a single transistor, and a byte (8 bits) is eight transistors that can collectively represent values from 0 (00000000) to 255 (11111111).

All other number systems that computers use — hex, octal — are just convenient shorthand for humans to read and write binary more compactly.

How Each Base Works

In any number system, a "base" tells you how many unique digits exist and what each position represents. In base 10 (decimal), the digits are 0–9 and each position is a power of 10. In base 2, the digits are 0–1 and each position is a power of 2.

PositionBase 10 valueBase 2 valueBase 16 value
Position 0 (rightmost)10⁰ = 12⁰ = 116⁰ = 1
Position 110¹ = 102¹ = 216¹ = 16
Position 210² = 1002² = 416² = 256
Position 310³ = 10002³ = 816³ = 4096

Binary (Base 2)

Binary uses only the digits 0 and 1. To read a binary number, multiply each digit by its positional power of 2 and sum the results:

Binary: 1 0 1 1 0 1
        ↓ ↓ ↓ ↓ ↓ ↓
  2⁵=32 2⁴=16 2³=8 2²=4 2¹=2 2⁰=1
   ×1   ×0    ×1   ×1   ×0   ×1
   32 +  0  +  8 +  4 +  0 +  1 = 45

So binary 101101 = decimal 45

Binary appears in: bitwise operations (&, |, ^, ~, <<, >>), boolean flags packed into an integer, network subnet masks, and low-level hardware registers.

Hexadecimal (Base 16)

Hex uses digits 0–9 and letters A–F (representing 10–15). One hex digit represents exactly 4 bits, which means one byte (8 bits) is always exactly two hex digits. This compact relationship with binary makes hex the universal shorthand for binary data.

// Converting hex to decimal:
0xFF = (15 × 16¹) + (15 × 16⁰) = 240 + 15 = 255
0x1A = (1 × 16¹) + (10 × 16⁰) = 16 + 10 = 26

// Converting between hex and binary (each hex digit = 4 bits):
0xA5 = 1010 0101
  A=1010  5=0101

0xFF = 1111 1111
  F=1111  F=1111

Hex appears in: memory addresses (0x7ffe5c24a0b0), CSS color codes (#FF5733), MAC addresses (00:1A:2B:3C:4D:5E), ASCII and Unicode code points (U+1F600), SHA-256 hashes, and cryptographic keys.

Octal (Base 8)

Octal uses digits 0–7. Each octal digit represents exactly 3 bits. Octal was more important in older computing systems and is still used today for Unix file permissions.

// Unix file permissions: chmod 755
// 7 = 111 binary = rwx (read, write, execute) for owner
// 5 = 101 binary = r-x (read, execute, no write) for group
// 5 = 101 binary = r-x (read, execute, no write) for others

// 644 = rw-r--r-- (common for files)
// 755 = rwxr-xr-x (common for executables and directories)

// In Python, prefix octal with 0o:
os.chmod("file.txt", 0o755)

Language Prefixes

BaseC/C++/Java/JSPythonExample
Binary0b0b0b1010 = 10
Octal0 or 0o0o0o17 = 15
Decimal(none)(none)255
Hexadecimal0x0x0xFF = 255

Bitwise Operations in Practice

Once you understand binary, bitwise operations become straightforward. They're used to pack multiple boolean flags into a single integer, work with hardware registers, implement fast modulo-by-powers-of-2, and manipulate color channel values.

// Packing permission flags into one integer
const READ    = 0b001;  // 1
const WRITE   = 0b010;  // 2
const EXECUTE = 0b100;  // 4

const permissions = READ | WRITE;  // 0b011 = 3

// Checking a flag
if (permissions & READ) { /* user can read */ }
if (permissions & EXECUTE) { /* user can execute */ }  // false

// Extracting color channels from a 32-bit RGBA integer
const color = 0xFF5733FF;
const red   = (color >> 24) & 0xFF;  // 255
const green = (color >> 16) & 0xFF;  // 87
const blue  = (color >> 8)  & 0xFF;  // 51
const alpha = color & 0xFF;           // 255

Two's Complement: How Computers Store Negative Numbers

Binary as described above only represents positive integers. Real computers use two's complement to represent negative numbers using the same bit patterns — with the most significant bit acting as a sign bit.

To negate a number in two's complement:

  1. Write the positive number in binary
  2. Flip all the bits (one's complement)
  3. Add 1
8-bit two's complement examples:
 0 = 00000000
 1 = 00000001
 2 = 00000010
127 = 01111111   ← max positive value for 8-bit signed
-1 = 11111111   ← flip 00000001, add 1 → 11111110 + 1 = 11111111
-2 = 11111110
-128 = 10000000  ← min negative value for 8-bit signed

This is why 8-bit signed integers range from -128 to 127 (not -127 to 127), and why JavaScript bitwise operations work on 32-bit signed integers — the sign bit means -1 >>> 0 produces 4294967295 (the 32-bit unsigned interpretation).

Two's complement is also the reason the Year 2038 problem exists: Unix timestamps stored as 32-bit signed integers will overflow from the max positive value (2,147,483,647 = Jan 19 2038 03:14:07 UTC) to the max negative value, wrapping to a date in 1901. Modern systems use 64-bit timestamps to avoid this.

Further reading: MDN — Bitwise Operators

BC
Bill Crawford
Founder, Data Conversion Center

Bill Crawford is a data systems developer and technical founder with over 30 years of professional experience in accounting, finance, and business operations.

He holds a Bachelor's degree in Accounting and has spent more than three decades working within financial and operational environments. Over the past 10 years, he has been heavily involved in the development, implementation, and refinement of financial and enterprise data systems for both Fortune 500 companies and smaller organizations.

His work bridges finance and technology — combining deep domain knowledge in structured reporting and accounting workflows with hands-on SQL development and database architecture experience.

Bill founded DataConversionCenter.com to build practical, browser-based tools that simplify complex data challenges, including:

Rather than focusing on theoretical examples, his tools and articles are informed by real-world challenges encountered in enterprise reporting systems, financial databases, and operational data environments.

Professional Background

Bill's mission is to reduce friction in data workflows — particularly for professionals working with structured financial, operational, and reporting data.