Hexadecimal for Programmers

Why 0xFF beats 0b11111111 — and every place you'll find base-16 lurking in your code

Writing binary gets tedious fast. 0b1111111111111111 is sixteen characters long, and every digit looks identical after two seconds of staring. 0xFFFF communicates the same value in four. Hexadecimal is not a different number system — it is a compact notation for binary. One hex digit maps cleanly to exactly four binary digits, no remainders, no rounding errors. If you understand that mapping, you can read hex as fluently as decimal. Use our hex to ASCII converter to see the relationship in practice.

Base-16 Symbols: 0 Through F

Decimal has 10 symbols (0-9). Binary has 2 (0-1). Hexadecimal needs 16 symbols, so it borrows A through F from the alphabet to represent values 10 through 15. There is nothing special about the letters — A is just 10, F is just 15. The table below is the single most important reference for reading hex. Memorize it once and you will never need a calculator for basic hex conversion again.

DecimalBinary (4-bit)Hex
000000
100011
200102
300113
401004
501015
601106
701117
810008
910019
101010A
111011B
121100C
131101D
141110E
151111F

Why Hex Is Programmer Shorthand for Binary

One hex digit represents exactly four bits — a nibble. Two hex digits represent one byte. The alignment is perfect: no fractional digits, no wasted space. 0xA3 is 1010 0011. Split each hex digit and translate independently. This is not a coincidence — base-16 was chosen precisely because 16 = 2⁴. Octal (base-8) was popular in early computing because 8 = 2³ mapped cleanly to 3-bit groups, but modern byte-oriented architectures settled on hex because a byte is two hex digits exactly. This is the killer feature of hex: one glance at 0x7F tells you the top bit is 0 and the bottom seven are 1 — 0111 1111. Try reading that from a 16-character binary string.

Colors: The #RRGGBB Format

Web colors use hex because each color channel (red, green, blue) is exactly one byte — values 0 through 255, or 00 through FF in hex. #FF5733 means red=0xFF (255), green=0x57 (87), blue=0x33 (51). To make the color 50% darker, you AND each byte with 0x80 or right-shift by 1. To extract the green channel from a packed 32-bit color: (color >> 8) & 0xFF. Every CSS color you have ever written is a hex literal; every image processing pipeline uses bitwise shifts and masks on these hex values.

# Python: parse #FF5733
hex_color = "FF5733"
r = int(hex_color[0:2], 16)  # 255
g = int(hex_color[2:4], 16)  # 87
b = int(hex_color[4:6], 16)  # 51
# Darken by 50% using bitwise shift
darker = ((r >> 1) << 16) | ((g >> 1) << 8) | (b >> 1)
print(hex(darker))  # 0x7f2b19

Memory Addresses

Every memory address you see in a debugger or crash log is hex. 0x7fff5fbff8c0 is a 48-bit virtual address on x86-64. Stack addresses often start with 0x7f... (user space), heap addresses with lower values. Kernel addresses on Linux start with 0xffff.... When you see Segmentation fault at 0x0, you know it is a null pointer dereference — address zero. GDB, LLDB, and WinDbg all default to hex because memory is byte-addressable and hex aligns perfectly with byte boundaries. Our programmer calculator (64-bit) can convert any address between hex and decimal.

MAC Addresses, Unicode, and Binary Files

MAC addresses are six bytes written as hex: 00:1A:2B:3C:4D:5E. The first three bytes are the OUI (organizationally unique identifier) assigned to the manufacturer. Unicode code points use hex: U+1F600 is the grinning face emoji. The U+ prefix denotes a Unicode scalar value in hex. Hex dumps like xxd and hexdump display binary file contents as hex because raw bytes printed as ASCII would be unreadable. A PNG file always starts with 89 50 4E 47 — that is the magic number identifying it as PNG. Hex editors like HxD and Hex Fiend are essential tools for reverse engineering, file format forensics, and patching binaries.

Hex Literals in C, Python, and JavaScript

Every major language uses the 0x prefix for hex literals. 0xFF in C, Python, JavaScript, Go, Rust, Java, and C# all mean the exact same thing: decimal 255. Some languages offer additional formatting: C++14 added 0b for binary literals and ' as a digit separator — 0xFF'FF'FF'FF is a valid 32-bit literal. Python supports 0xFF_FF_FF_FF. JavaScript has 0xFF but notably no binary literal syntax before ES6 (now 0b11111111). The consistency of 0x across languages is one of the few genuine standards in programming — you can read hex in any codebase without looking up the syntax.

// Same value, three languages
int x = 0xFF;          // C
x = 0xFF               // Python
let x = 0xFF;          // JavaScript
// All equal 255. All mean "all 8 bits are 1."

Hex-to-Binary Mental Conversion Trick

You do not need to convert hex to decimal to understand it. Convert hex to binary directly: each hex digit becomes exactly four bits. 0xDEAD → D=1101, E=1110, A=1010, D=1101 → 1101 1110 1010 1101. Going the other way: group your binary in chunks of four from the right, pad the leftmost group with zeros if needed, and translate each chunk. 101 1101 0011 → pad to 0101 1101 0011 → 5, D, 3 → 0x5D3. With practice, this becomes automatic — you stop seeing hex as an opaque code and start seeing it as the binary it represents. Keep our hex to ASCII converter bookmarked for quick lookups while you build the mental mapping.