The Hexadecimal Number System

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
000000Zero
110001One
220010Two
330011Three
440100Four
550101Five
660110Six
770111Seven
881000Eight
991001Nine
A101010A for ten
B111011B for eleven
C121100C for twelve
D131101D for thirteen
E141110E for fourteen
F151111F 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.

DecHexBinDecHexBinDecHexBinDecHexBin
000000000006440010000001288010000000192C011000000
101000000016541010000011298110000001193C111000001
202000000106642010000101308210000010194C211000010
303000000116743010000111318310000011195C311000011
404000001006844010001001328410000100196C411000100
505000001016945010001011338510000101197C511000101
606000001107046010001101348610000110198C611000110
707000001117147010001111358710000111199C711000111
808000010007248010010001368810001000200C811001000
909000010017349010010011378910001001201C911001001
100A00001010744A010010101388A10001010202CA11001010
110B00001011754B010010111398B10001011203CB11001011
120C00001100764C010011001408C10001100204CC11001100
130D00001101774D010011011418D10001101205CD11001101
140E00001110784E010011101428E10001110206CE11001110
150F00001111794F010011111438F10001111207CF11001111
1610000100008050010100001449010010000208D011010000
1711000100018151010100011459110010001209D111010001
322000100000966001100000160A010100000224E011100000
4830001100001127001110000176B010110000240F011110000
633F001111111277F01111111191BF10111111255FF11111111

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.