The Hexadecimal Number System
Table of Contents
The Base-16 Number System
Hexadecimal (hex) is a base-16 number system that uses sixteen distinct symbols to represent values. It is one of the most widely used number systems in computing, serving as a human-friendly representation of binary-coded values. The term "hexadecimal" combines the Greek "hex" (six) and the Latin "decem" (ten), reflecting its base of sixteen.
In a positional number system, each digit's position represents a power of the base. In decimal (base-10), the number 345 means 3×10² + 4×10¹ + 5×10⁰ = 300 + 40 + 5 = 345. Similarly, in hexadecimal, the number 1A3 means 1×16² + A×16¹ + 3×16⁰ = 256 + 160 + 3 = 419 in decimal.
Hexadecimal is particularly useful in computing because it provides a compact representation of binary data. Each hexadecimal digit represents exactly 4 bits (a nibble), and two hexadecimal digits represent exactly 8 bits (a byte). This makes conversion between hex and binary trivial — simply replace each hex digit with its 4-bit binary equivalent.
The relationship between common number systems is worth understanding. Binary (base-2) is how computers store data internally. Decimal (base-10) is how humans naturally count. Octal (base-8) was historically used in computing but has been largely replaced by hexadecimal. Hexadecimal (base-16) serves as the bridge between human-readable notation and binary data.
Hexadecimal numbers are typically prefixed with "0x" in programming languages (C, Java, Python, JavaScript) to distinguish them from decimal numbers. In some contexts, other notations are used: "h" suffix (1A3h in assembly language), "#" prefix (#FF0000 in CSS colors), or "\x" prefix (\x41 in escape sequences).
Hexadecimal Digits: 0-9 and A-F
The hexadecimal system uses sixteen symbols: the digits 0 through 9 and the letters A through F. The letters represent values from 10 to 15. Both uppercase (A-F) and lowercase (a-f) are accepted, though conventions vary by context.
| Hex Digit | Decimal Value | Binary (4 bits) | Memory Aid |
|---|---|---|---|
| 0 | 0 | 0000 | Zero |
| 1 | 1 | 0001 | One |
| 2 | 2 | 0010 | Two |
| 3 | 3 | 0011 | Three |
| 4 | 4 | 0100 | Four |
| 5 | 5 | 0101 | Five |
| 6 | 6 | 0110 | Six |
| 7 | 7 | 0111 | Seven |
| 8 | 8 | 1000 | Eight |
| 9 | 9 | 1001 | Nine |
| A | 10 | 1010 | A for ten |
| B | 11 | 1011 | B for eleven |
| C | 12 | 1100 | C for twelve |
| D | 13 | 1101 | D for thirteen |
| E | 14 | 1110 | E for fourteen |
| F | 15 | 1111 | F for fifteen |
A useful mnemonic: the first hex digit that is not a number is A, which represents 10. Think of it as continuing the count after 9: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. After F (15), the next value is 10 (sixteen in decimal), just as after 9 in decimal comes 10 (ten).
In CSS colors, hex digits are used extensively. The color #FF8000 breaks down as FF (red=255), 80 (green=128), 00 (blue=0), producing an orange color. Understanding hex digits allows you to intuitively adjust colors: increasing the first two digits makes the color more red, increasing the middle two makes it more green, and increasing the last two makes it more blue.
Case conventions for hexadecimal vary by context. CSS typically uses uppercase (#FF0000). Programming languages often use lowercase (0xff0000). MAC addresses use uppercase with colons or hyphens (AA:BB:CC:DD:EE:FF). Cryptographic hashes are almost always lowercase (sha256 returns lowercase hex). The choice is usually aesthetic, as most systems accept either case.
Converting Hexadecimal to Decimal
Converting hexadecimal to decimal uses the positional value method. Each hex digit is multiplied by 16 raised to the power of its position (counting from right to left, starting at 0), and the results are summed.
The general formula for a hex number with digits dₙdₙ₋₁...d₁d₀ is:
Decimal = dₙ × 16ⁿ + dₙ₋₁ × 16ⁿ⁻¹ + ... + d₁ × 16¹ + d₀ × 16⁰
Example 1: Convert 2F to decimal
- 2 is in the 16¹ position: 2 × 16 = 32
- F (15) is in the 16⁰ position: 15 × 1 = 15
- Sum: 32 + 15 = 47
- Therefore, 2F₁₆ = 47₁₀
Example 2: Convert 1A3 to decimal
- 1 is in the 16² position: 1 × 256 = 256
- A (10) is in the 16¹ position: 10 × 16 = 160
- 3 is in the 16⁰ position: 3 × 1 = 3
- Sum: 256 + 160 + 3 = 419
- Therefore, 1A3₁₆ = 419₁₀
Example 3: Convert FF to decimal
- F (15) is in the 16¹ position: 15 × 16 = 240
- F (15) is in the 16⁰ position: 15 × 1 = 15
- Sum: 240 + 15 = 255
- Therefore, FF₁₆ = 255₁₀
This explains why the maximum value of a byte (8 bits) is represented as FF in hexadecimal — it equals 255 in decimal, which is 2⁸ - 1, the maximum value representable with 8 bits.
Example 4: Convert 3E8 to decimal
- 3 is in the 16² position: 3 × 256 = 768
- E (14) is in the 16¹ position: 14 × 16 = 224
- 8 is in the 16⁰ position: 8 × 1 = 8
- Sum: 768 + 224 + 8 = 1000
- Therefore, 3E8₁₆ = 1000₁₀
Powers of 16 are useful to memorize for quick conversions: 16⁰ = 1, 16¹ = 16, 16² = 256, 16³ = 4,096, 16⁴ = 65,536, 16⁵ = 1,048,576. Recognizing these values helps you estimate the magnitude of hex numbers at a glance.
Converting Decimal to Hexadecimal
Converting decimal to hexadecimal uses the repeated division method. Divide the decimal number by 16, record the remainder, then divide the quotient by 16 again. Continue until the quotient is 0. The hex number is the remainders read from last to first.
Example 1: Convert 255 to hex
- 255 ÷ 16 = 15 remainder 15 (F)
- 15 ÷ 16 = 0 remainder 15 (F)
- Read remainders bottom to top: FF
- Therefore, 255₁₀ = FF₁₆
Example 2: Convert 419 to hex
- 419 ÷ 16 = 26 remainder 3
- 26 ÷ 16 = 1 remainder 10 (A)
- 1 ÷ 16 = 0 remainder 1
- Read remainders bottom to top: 1A3
- Therefore, 419₁₀ = 1A3₁₆
Example 3: Convert 1000 to hex
- 1000 ÷ 16 = 62 remainder 8
- 62 ÷ 16 = 3 remainder 14 (E)
- 3 ÷ 16 = 0 remainder 3
- Read remainders bottom to top: 3E8
- Therefore, 1000₁₀ = 3E8₁₆
An alternative method for small numbers is to find the largest power of 16 that fits, then work downward. For 419: the largest power of 16 ≤ 419 is 256 (16²). 419 ÷ 256 = 1 remainder 163. The largest power of 16 ≤ 163 is 16 (16¹). 163 ÷ 16 = 10 remainder 3. So the digits are 1, A (10), 3 → 1A3.
Hexadecimal and Binary Conversion
Converting between hexadecimal and binary is exceptionally simple because each hex digit maps directly to exactly 4 binary digits. This 1:4 relationship makes hex a natural shorthand for binary.
To convert hex to binary: replace each hex digit with its 4-bit binary equivalent from the table above.
Example: Convert 4A2F to binary
- 4 → 0100
- A → 1010
- 2 → 0010
- F → 1111
- Result: 0100101000101111
To convert binary to hex: group the binary digits into groups of 4 from right to left (add leading zeros if needed), then convert each group to its hex digit.
Example: Convert 110101101 to hex
- Pad to multiple of 4: 000110101101
- Group: 0001 1010 1101
- Convert: 1 A D
- Result: 1AD
This direct relationship is why hexadecimal is the preferred way to display binary data. Instead of writing 11111111, you can simply write FF. Instead of 110000001010100000000001, you can write C0A801. The mental conversion is almost instantaneous once you memorize the 16 hex-to-binary mappings.
Hexadecimal in Computing
Hexadecimal appears throughout computing in many different contexts. Understanding these applications helps you recognize hex values in the wild and know what they represent.
Color Codes (Web and Graphics)
Web colors use hexadecimal notation with the format #RRGGBB, where RR represents the red component, GG represents green, and BB represents blue. Each component ranges from 00 (0, no color) to FF (255, full intensity). For example, #FF0000 is pure red, #00FF00 is pure green, #0000FF is pure blue, and #FFFFFF is white (all colors at full intensity). The shorthand notation #RGB is equivalent to #RRGGBB — #F00 means #FF0000. With alpha transparency, the format becomes #RRGGBBAA, where AA is the opacity (FF=opaque, 00=transparent).
Memory Addresses
Computer memory addresses are represented in hexadecimal. A 32-bit system can address up to 4 GB of memory, with addresses ranging from 0x00000000 to 0xFFFFFFFF. A 64-bit system extends this to addresses like 0x00007FFF12345678. Debuggers and system tools display memory addresses in hex because it is more compact than binary and more natural for working with binary data than decimal.
MAC Addresses
Network interface MAC addresses are 48-bit identifiers written as six pairs of hex digits, typically separated by colons or hyphens: AA:BB:CC:DD:EE:FF or AA-BB-CC-DD-EE-FF. The first three octets identify the manufacturer (OUI), and the last three are the device identifier. For example, 00:1A:2B is a prefix assigned to a specific vendor.
Error Codes and Status Values
Operating systems and APIs commonly use hex codes for error and status values. Windows uses hex HRESULT values like 0x80070005 (E_ACCESSDENIED). HTTP status codes are sometimes shown in hex in low-level networking tools. Linux signal numbers are occasionally referenced in hex in kernel code.
File Signatures (Magic Numbers)
File formats begin with specific byte sequences (magic numbers) that identify the format. These are typically displayed in hex: PNG files start with 89 50 4E 47 0D 0A 1A 0A, JPEG files start with FF D8 FF, PDF files start with 25 50 44 46 (%PDF), and ZIP files start with 50 4B 03 04 (PK..). Knowing these signatures helps identify file types regardless of their extension.
Unicode Code Points
Unicode characters are identified by hex code points: U+0041 for 'A', U+4E2D for '中', U+1F600 for '😀'. The "U+" prefix indicates a Unicode code point, and the hex value maps to the character's position in the Unicode table. HTML hex entities use a similar notation: A for 'A'.
Cryptographic Hashes
Cryptographic hash functions (MD5, SHA-1, SHA-256) produce fixed-size outputs displayed in hex. MD5 produces 32 hex characters (128 bits), SHA-1 produces 40 hex characters (160 bits), and SHA-256 produces 64 hex characters (256 bits). These hex strings serve as digital fingerprints for files, messages, and certificates.
Hexadecimal Conversion Table (0-255)
This table shows the first 256 values (one byte's worth) in decimal, hexadecimal, binary, and octal. The first 16 values are the most important to memorize, as they form the building blocks for all hex conversions.
| Dec | Hex | Bin | Dec | Hex | Bin | Dec | Hex | Bin | Dec | Hex | Bin |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 00 | 00000000 | 64 | 40 | 01000000 | 128 | 80 | 10000000 | 192 | C0 | 11000000 |
| 1 | 01 | 00000001 | 65 | 41 | 01000001 | 129 | 81 | 10000001 | 193 | C1 | 11000001 |
| 2 | 02 | 00000010 | 66 | 42 | 01000010 | 130 | 82 | 10000010 | 194 | C2 | 11000010 |
| 3 | 03 | 00000011 | 67 | 43 | 01000011 | 131 | 83 | 10000011 | 195 | C3 | 11000011 |
| 4 | 04 | 00000100 | 68 | 44 | 01000100 | 132 | 84 | 10000100 | 196 | C4 | 11000100 |
| 5 | 05 | 00000101 | 69 | 45 | 01000101 | 133 | 85 | 10000101 | 197 | C5 | 11000101 |
| 6 | 06 | 00000110 | 70 | 46 | 01000110 | 134 | 86 | 10000110 | 198 | C6 | 11000110 |
| 7 | 07 | 00000111 | 71 | 47 | 01000111 | 135 | 87 | 10000111 | 199 | C7 | 11000111 |
| 8 | 08 | 00001000 | 72 | 48 | 01001000 | 136 | 88 | 10001000 | 200 | C8 | 11001000 |
| 9 | 09 | 00001001 | 73 | 49 | 01001001 | 137 | 89 | 10001001 | 201 | C9 | 11001001 |
| 10 | 0A | 00001010 | 74 | 4A | 01001010 | 138 | 8A | 10001010 | 202 | CA | 11001010 |
| 11 | 0B | 00001011 | 75 | 4B | 01001011 | 139 | 8B | 10001011 | 203 | CB | 11001011 |
| 12 | 0C | 00001100 | 76 | 4C | 01001100 | 140 | 8C | 10001100 | 204 | CC | 11001100 |
| 13 | 0D | 00001101 | 77 | 4D | 01001101 | 141 | 8D | 10001101 | 205 | CD | 11001101 |
| 14 | 0E | 00001110 | 78 | 4E | 01001110 | 142 | 8E | 10001110 | 206 | CE | 11001110 |
| 15 | 0F | 00001111 | 79 | 4F | 01001111 | 143 | 8F | 10001111 | 207 | CF | 11001111 |
| 16 | 10 | 00010000 | 80 | 50 | 01010000 | 144 | 90 | 10010000 | 208 | D0 | 11010000 |
| 17 | 11 | 00010001 | 81 | 51 | 01010001 | 145 | 91 | 10010001 | 209 | D1 | 11010001 |
| 32 | 20 | 00100000 | 96 | 60 | 01100000 | 160 | A0 | 10100000 | 224 | E0 | 11100000 |
| 48 | 30 | 00110000 | 112 | 70 | 01110000 | 176 | B0 | 10110000 | 240 | F0 | 11110000 |
| 63 | 3F | 00111111 | 127 | 7F | 01111111 | 191 | BF | 10111111 | 255 | FF | 11111111 |
Key values to memorize: 10₁₆ = 16₁₀, 20₁₆ = 32₁₀, 40₁₆ = 64₁₀, 80₁₆ = 128₁₀, FF₁₆ = 255₁₀. These boundaries appear constantly in computing — 128 is the boundary between ASCII and extended ASCII, 255 is the maximum byte value, and powers of 2 (16, 32, 64, 128) are fundamental to computer architecture.
Hexadecimal Arithmetic
Hexadecimal arithmetic follows the same rules as decimal arithmetic, but with base 16. Understanding hex addition and subtraction is useful for manual calculations involving memory addresses, offsets, and sizes.
Hex Addition
Add hex digits column by column from right to left, carrying over when the sum reaches 16 (not 10 as in decimal).
- Example: 1A + 2F = ?
- Right column: A(10) + F(15) = 25. 25 ÷ 16 = 1 remainder 9. Write 9, carry 1.
- Left column: 1 + 2 + 1(carry) = 4. Write 4.
- Result: 1A + 2F = 49
- Verification: 26 + 47 = 73 = 4×16 + 9 = 49₁₆ ✓
Hex Subtraction
Subtract hex digits column by column, borrowing 16 (not 10) when needed.
- Example: 3E - 1F = ?
- Right column: E(14) - F(15). Borrow from left: 14 + 16 - 15 = 15 = F.
- Left column: 3 - 1(borrowed) - 1 = 1.
- Result: 3E - 1F = 1F
- Verification: 62 - 31 = 31 = 1×16 + 15 = 1F₁₆ ✓
For complex hex calculations, most programmers convert to decimal, perform the calculation, and convert back. However, for simple operations like adding an offset to a memory address (e.g., 0x1000 + 0x20 = 0x1020), hex arithmetic becomes second nature with practice.