The core idea: positional notation
A number in any base = the sum of each digit × the base's positional weight. Binary 1011 = 1×8 + 0×4 + 1×2 + 1×1 = 11. Hex uses A–F for 10–15, so 0xFF = 15×16 + 15 = 255. Once this clicks, conversion is just arithmetic.
Why programmers love hex
One hex digit maps exactly to 4 binary digits, so a byte (8 bits) is always 2 hex characters. Memory addresses, byte sequences and colors all use it for this reason: #FF5733 = R:255, G:87, B:51 — three hex pairs are three channel intensities.
Common pitfalls
- Lost leading zeros:
"007"parses to the number 7 and changes when converted back; - Big-number precision: beyond JavaScript's safe integer (2^53) results are unreliable — treat as strings or use BigInt;
- Floats are never exact: 0.1 is an infinitely repeating binary fraction; base conversion is exact for integers only, mind rounding for fractions.
Handy conversions
| Decimal | Binary | Octal | Hex |
|---|---|---|---|
| 10 | 1010 | 12 | A |
| 255 | 1111 1111 | 377 | FF |
| 1024 | 100 0000 0000 | 2000 | 400 |
| 65535 | 1111 1111 1111 1111 | 177777 | FFFF |
Code examples
// Parsing: the second argument is the radix
parseInt('FF', 16); // 255
Number.parseInt('1010', 2); // 10
// Formatting: toString(radix)
(255).toString(16); // "ff"
(10).toString(2); // "1010"
// Colour channels to hex (pad each channel to two digits)
'#' + [255, 87, 51].map(v => v.toString(16).padStart(2, '0')).join('');
// => "#ff5733"
Three limitations to know
- Leading zeros vanish:
"007"parses to 7 and never comes back — treat IDs and codes as strings; - Big integers lose precision: beyond
Number.MAX_SAFE_INTEGER(2^53−1) useBigIntor strings; - Fractions are approximations: 0.1 is an infinite binary fraction; only the integer part converts exactly.
Follow-up questions
Why are colours written as six hex digits? Each pair encodes a 0–255 channel, so R/G/B is exactly six digits and maps losslessly to one byte each. Is hex always shorter? For the same value, yes — a larger radix needs fewer digits.
Real-world cases: three base-conversion pitfalls
- "Port to hex does not match": decimal 255 is FF; do not confuse base conversion with byte splitting.
- "Large integers lose their last digits": JavaScript is precise only to ~2^53, so handle very long integers as strings / BigInt.
- "Binary mask computed wrong": convert the mask to decimal, verify the bits, then decide which to take — avoid counting 0/1 by eye.
FAQ
Are decimals supported? Integers for now; scale decimals up to integers first. Is the sign preserved? Yes, across all bases. Up to which base? Base 36 (all of 0-9 and a-z). Any precision loss? No — exact BigInt arithmetic.
Try them: base converter, color converter
Where it shows up in practice
Base conversion looks basic but goes wrong in specific contexts; what matters is knowing what each context needs.
- Permission bits and masks: file modes, netmasks and feature flags appear as octal or binary. Read them bit by bit rather than treating the whole as one decimal number.
- Colours and identifiers: hex is common for colours and hashes; case is irrelevant but length must match exactly — a wrong length usually means truncation or padding.
- Protocol fields: network protocols and hardware registers use fixed widths, so pad with leading zeros or the parser reads the wrong field.
- Short links and encodings: converting an incrementing number to a higher base shortens display length, but choose the alphabet carefully and avoid case ambiguity.
- Large integers: values beyond the safe integer range must be handled as strings and never pass through floating point, or trailing digits are silently rewritten.
Verification habit
Convert the result back and compare with the input. For critical data, also check length and range — eyeballing is exactly how a single differing digit goes unnoticed.
Tools and human error
Conversion mistakes almost always come from manual work: a mistyped digit, missing leading zeros, a confused prefix. Do the conversion in tooling or code and verify automatically, leaving humans to judge whether the result matches expectations rather than to compute it.