Every hex digit is worth sixteen of the one to its right
Base 16 works the same way base 10 does. Move one column left and the weight multiplies. In decimal the multiplier is ten, so 407 reads as four hundreds, no tens, seven ones. In hex the multiplier is sixteen, so 1A7 reads as one 256, ten 16s, seven 1s, which lands on 423.
The awkward part is the letters. A through F carry the values ten through fifteen, because base 16 needs sixteen single characters and the digits run out at nine. Once you read A as ten and F as fifteen, the arithmetic stops being unusual.
| Hex | Decimal | Binary | Hex | Decimal | Binary |
|---|---|---|---|---|---|
| 0 | 0 | 0000 | 8 | 8 | 1000 |
| 1 | 1 | 0001 | 9 | 9 | 1001 |
| 2 | 2 | 0010 | A | 10 | 1010 |
| 3 | 3 | 0011 | B | 11 | 1011 |
| 4 | 4 | 0100 | C | 12 | 1100 |
| 5 | 5 | 0101 | D | 13 | 1101 |
| 6 | 6 | 0110 | E | 14 | 1110 |
| 7 | 7 | 0111 | F | 15 | 1111 |
The binary column is why hex stuck around. One hex digit maps onto exactly four bits with no remainder, so a byte is always two hex characters and never one and a bit.
Reading the ledger instead of trusting the total
Most converters hand back a number and nothing else. When the number looks wrong, you have no way to tell whether you mistyped a digit or misread the base.
The ledger under the result breaks the value apart column by column. Type 3E8 and you get three rows. The 3 sitting in the 162 column contributes 768. The E, worth 14, sits in the 161 column and contributes 224. The 8 in the ones column contributes 8. Add them and you have 1000.
Rows for zero digits stay dim rather than disappearing, because a missing column is the most common transcription error there is. Dropping a zero from 0x1000 divides the value by sixteen, and a dim row in the right place makes the mistake visible.
Where a lot of hex converters quietly go wrong
Here is the failure worth knowing about, because it is silent and it produces a plausible looking answer.
JavaScript numbers are 64 bit floating point. Whole numbers stay exact up to 9007199254740991, which is 1FFFFFFFFFFFFF, fourteen hex digits. Past that point the format runs out of room in the mantissa and starts rounding to the nearest representable value.
Ask a browser for parseInt("FFFFFFFFFFFFFFFF", 16) and it answers 18446744073709552000. The correct value is 18446744073709551615. The last four digits are fabricated by rounding, and nothing in the output warns you.
This page runs on BigInt instead, which carries arbitrary precision. A 64 bit maximum, a 128 bit UUID or a 256 bit hash all convert exactly, no matter how many digits you paste in.
Sixty four bit values are not exotic. Database identifiers, file offsets, memory addresses on any modern machine and Unix timestamps in nanoseconds all live above the safe integer limit. Anyone who has pasted a hex snowflake ID into a converter and got a number ending in zeros has hit this.
The same bits, two different numbers
Hex describes a bit pattern. Whether that pattern means a large positive number or a small negative one depends on how the surrounding code declares the variable, and hex alone does not record the decision.
Take FFFFFFFF. Read as an unsigned 32 bit integer it is 4294967295. Read as a signed 32 bit integer it is negative one, because the top bit is set and two's complement treats a set high bit as the sign. Both readings are correct. They answer different questions about the same four bytes.
The signed panel switches between 8, 16, 32 and 64 bit widths so you get both readings side by side. Width matters as much as the bits do. FF is 255 unsigned, negative one as a signed byte, and a plain 255 at any wider width, because the high bit of a 16 bit word is nowhere near it.
This is where error codes trip people up. A function returning 0xFFFFFFFE has almost certainly returned negative two, not four billion.
Who ends up needing this
Web developers pulling colour channels apart. A hex colour is three bytes stacked together, so #FF5733 splits into FF, 57 and 33, giving red 255, green 87, blue 51. Converting the whole string at once gives 16734003, which is the packed integer some graphics APIs want and no use at all for reading channel values. For colours specifically, the Hex to RGB Converter does the splitting for you.
Embedded and systems work brings different traffic. Register offsets, memory addresses, opcode values and status flags arrive in hex from datasheets and debuggers, then need to be decimal for arithmetic. Bit level work usually wants Hex to Binary rather than decimal, and the Bitwise Calculator covers masking and shifting.
Students working through number systems tend to want the reverse trip as well. Decimal to Hex runs the division and remainder method in the other direction. Binary to Decimal and Octal to Decimal use identical place value arithmetic with a different multiplier, and the All Number Converter shows every base at once when the target is a comparison rather than a single answer.
What this converter will not do
Integers only. Hex fractions like 1.8p3 and IEEE 754 hex float literals are rejected rather than guessed at, because the bit layout of a float is a separate problem from place value arithmetic.
No negative input. A leading minus sign is not accepted, since negative values in hex are normally expressed as two's complement bit patterns rather than signed text. Use the signed panel to read a pattern as negative.
Prefixes are tolerated, not required. A leading 0x, spaces, commas and _ separators are stripped before parsing, so pasting 0xDEAD_BEEF straight out of source works. Anything left that is not a hex digit is named in the message under the input rather than being silently dropped, because a converter that ignores a stray character will happily return the wrong number.
Everything runs inside the page. No value is sent to a server, nothing is stored between visits, and closing the tab ends it.
