A base is a grouping rule, and where converters lose digits
Every place in a written number is worth the base times the place to its right. Decimal groups by ten, binary by two, octal by eight, hexadecimal by sixteen. The quantity never changes: 255, 0xFF, 0o377 and 0b1111_1111 are four spellings of one number, the way a distance is the same whether you write it in miles or kilometres. Hexadecimal earns its place in computing because sixteen is two to the fourth, so one hex digit is exactly four bits and the two notations line up with no arithmetic.
The reason to use a converter rather than a language built-in is precision. Most converters, and every JavaScript function that returns a plain number, hold the value in a double precision float, which is exact for integers only up to 9,007,199,254,740,991. Above that the low bits are rounded away and you get a result that ends in zeros which were never in your input. A 64-bit register value, a Snowflake ID or a device serial all sit past that line. This page parses and prints with BigInt, which has no fixed width, so a 64-bit mask survives the round trip digit for digit.
The other failure is silent reinterpretation. A spreadsheet reads a hex value that happens to be all digits as a decimal number and drops the leading zero; C and Java read a leading zero as octal, so 010 is eight. Nothing here guesses that way: the base comes from your prefix or your button, and it is stated in words above the results.
Which base the input is read as
One box takes the input, and four results come out at once, so the only decision is what the digits you typed already mean.
- A prefix wins. Type
0b,0o,0dor0xin front and the base is settled, whichever button is selected. - Auto, with no prefix: any of the letters a to f means hexadecimal, and everything else is read as decimal. It deliberately never guesses binary, because an unprefixed 1010 is far more often one thousand and ten than it is ten.
- Press a base to be explicit. That is the mode to use for binary and octal without prefixes, and for a hex value such as
4321that would otherwise look decimal. - One exception worth knowing: when you have chosen Hex, a leading
0bor0dis read as hex digits rather than as a prefix, because both are valid hexadecimal numbers in their own right. - Spaces and underscores are ignored anywhere, so
1101 1110and0xDEAD_BEEFboth work. Commas are not: a comma is a decimal point in much of the world, and reading 1,5 as fifteen would be worse than rejecting it. - A leading minus sign is kept and the results carry it. Anything else, including a decimal point, is reported with the character and its position rather than being quietly dropped.
How to convert a value and take it into code
- Paste or type the number. The sample loaded on the page,
0xDEAD_BEEF, shows the prefix and the underscore separator at the same time. - Check the line under the buttons. It says which base was used and why, so a wrong reading shows up before you copy the answer anywhere.
- If the reading is wrong, press the base you meant. The four results update as you type.
- Read the four rows. The one matching your input is tagged, which is a quick check that you and the tool agree.
- Tick the prefix box if the value is going into source code. The copies then come out as
0b1010,0o777and0xFFrather than as bare digits. - Press Copy on the row you need. The copy is exactly what is on screen, with no separators and no trailing spaces to clean up.
How to read the bit view
Below the results the value is drawn as a register: bits grouped in fours, boxed one byte at a time, with the hex value of each byte underneath. The small number above each group is the index of its leftmost bit, and bit 0 is on the far right.
- Pick the width your documentation uses: 8, 16, 32 or 64 bits. The width only changes the picture, never the four results above it.
- To check a flag, find the index above the group, count left from the rightmost bit of that group, and read the digit. Bit 6 set in a status word means that flag is on; in code the same test is a bitwise AND against a mask with only bit 6 set.
- Compare the per-byte hex against a memory dump. Because one hex digit is one group of four bits, a mismatch shows up as a single wrong nibble rather than as a wrong number.
- If the value is too large for the width you picked, the tool says how many bits it needs and offers the smallest width that holds it, which is the question you are really asking before writing a value into a fixed field.
Negative values and two’s complement
Hardware has no minus sign, only bits, so a negative number is stored as a pattern that behaves like a negative number under addition. The scheme in use almost everywhere is two’s complement: write the positive value, flip every bit, add 1. In 8 bits, 5 is 00000101, so -5 is 11111011. The top bit ends up acting as a sign flag, and the same adder circuit handles both signs with no special case.
The tick box under the bit view switches between that and plain sign and magnitude, which is the way people write negatives on paper: a minus sign followed by the bits of the size. Leave two’s complement on when you are matching a debugger, a memory dump or a protocol field. Turn it off when you only want to see the magnitude in binary.
| Width | Unsigned range | Signed range |
|---|---|---|
| 8-bit | 0 to 255 | -128 to 127 |
| 16-bit | 0 to 65,535 | -32,768 to 32,767 |
| 32-bit | 0 to 4,294,967,295 | -2,147,483,648 to 2,147,483,647 |
| 64-bit | 0 to 18,446,744,073,709,551,615 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
The signed ranges are not symmetric. Two’s complement has a single pattern for zero, which frees the one that would be minus zero for an extra negative value, so 8 bits reach -128 but stop at 127. Hence a classic overflow: negating the most negative value returns it unchanged, because its positive twin does not exist at that width.
Getting the result out of the page
- Into code: tick the prefix box first. A bare
1010pasted into a source file is a thousand and ten in every mainstream language;0b1010is ten. - Into a spreadsheet: format the cell as text before pasting a long hex or binary value. Otherwise a value made only of digits is read as a number and the leading zeros are lost.
- On a phone: Copy puts the value on the system clipboard, so a long press and Paste works in any app. Some in-app browsers block the clipboard; there, select the text by hand.
- Into a bug report: quote the decimal and the hex together. Decimal is what a log or an API returns, hex is what the register documentation is written in, and half of these conversations go wrong because only one was given.
The same conversion in other tools
- JavaScript:
(255).toString(2)andparseInt("ff", 16)are fine for small values, and both lose precision past 2^53. UseBigInt("0xffffffffffffffff")andvalue.toString(16)for anything wider, which is what this page does. - Python:
int("ff", 16)parses, andbin(),oct()andhex()print with the prefix already attached. Python integers are arbitrary precision, andformat(n, "032b")pads to a fixed width. - C, Java, Rust and friends: the literals are the prefixes above, with the trap that a bare leading zero means octal in C and Java, so 010 is 8. Rust and Python 3 removed that spelling and require
0o. - Spreadsheets:
HEX2DEC,BIN2DEC,DEC2HEXand their siblings work only within narrow limits, historically ten hex digits or ten bits, and they treat the top bit as a sign. Wider values return an error rather than a wrong answer. - Shell:
printf "%x" 255prints ff, andecho $((16#ff))parses hex in bash without a prefix. - Calculator apps: Windows Calculator in Programmer mode and the macOS Calculator in Programmer view both show all four bases with a bit grid, fixed width and usually no wider than 64 bits.
Limits worth knowing before you trust the output
- Whole numbers only. A decimal point is rejected, with the character and position named, rather than truncated. Fractions in binary are a different job and a different set of rounding traps.
- This is not a float inspector. The bits shown are the bits of an integer. The IEEE 754 layout that a language uses to store 3.14 in 64 bits, with a sign exponent and mantissa, is not what appears here.
- Byte order is not shown. The bit view prints the most significant bit first. How those bytes sit in memory or on the wire depends on the endianness of the machine or the protocol, and a little endian dump lists them the other way round.
- Width is a display choice. Changing 32-bit to 64-bit does not sign extend or truncate the value in the results above; it only redraws the picture. A value that does not fit is reported rather than wrapped.
- Check the base you were given. The commonest error in practice is not arithmetic, it is a value copied out of a document that never said which base it was in. Confirm that before you convert.
Frequently asked questions
How do I convert binary to decimal by hand?
Give each bit the value of its place, doubling from right to left: 1, 2, 4, 8, 16, 32 and so on. Add up the places where the bit is 1 and you have the decimal value, so 1011 is 8 plus 2 plus 1, which is 11. The faster method for long strings is to read left to right and double as you go: start at 0, and for each bit double what you have and add the bit. For 1011 that is 0, then 1, then 2, then 5, then 11. Both give the same answer, and the second one needs no place values written down.
What do the 0b, 0o and 0x prefixes mean?
They tell a reader, human or machine, which base the digits are written in: 0b for binary, 0o for octal, 0x for hexadecimal, and in a few languages 0d for decimal. They are not part of the value. 0b1010, 0o12, 10 and 0xA are four spellings of the same number. This page accepts all four, and a prefix wins over the base you picked, with one exception: if you have explicitly chosen hexadecimal, a leading 0b or 0d is read as hex digits, because 0b and 0d are themselves valid hexadecimal numbers.
Why do other converters get large hexadecimal values wrong?
Most of them parse into a double precision float, which holds integers exactly only up to 9007199254740991, or 2 to the power of 53 minus 1. Above that, the low bits are rounded away and the converter prints a number ending in a run of zeros that was never in your input. It is the same reason parseInt in JavaScript cannot be trusted with a 64-bit register dump. This page parses and prints with BigInt, which has no fixed width, so a 64-bit mask or a 512-bit key round trips digit for digit.
How is a negative number written in binary?
Two ways, and they answer different questions. Sign and magnitude is what people write on paper: a minus sign followed by the bits of the size, so -5 is -101. Two's complement is what hardware stores: the value is held in a fixed number of bits with no separate sign character, and the top bit carries a negative weight. In 8 bits, -5 is 11111011. The bit view here shows either one. Leave the two's complement box ticked when you are matching a debugger or a memory dump, and untick it when you only want to see the magnitude.
What is two's complement, and why is -1 all ones?
To find the pattern for a negative value at a given width, write the positive value in binary, flip every bit, then add 1. For -1 in 8 bits: 00000001 flips to 11111110, add 1 and you get 11111111. The point of the scheme is that addition and subtraction work with one circuit and no special case for the sign, and that there is exactly one representation of zero. The cost is an asymmetric range: 8 bits run from -128 to 127, not -127 to 127, because the pattern that would be minus zero is used for the extra negative value.
Can this tool convert fractions such as 0.625?
No. It converts whole numbers only, and a decimal point is reported as an invalid character rather than silently truncated, because quietly dropping the fraction is how wrong answers get copied into code. Fractions are worth doing by hand anyway, since the rule is short: multiply the fraction by 2 repeatedly and read off the integer part each time, so 0.625 becomes 0.101 in binary. Values such as 0.1 never terminate in binary, which is the root of the floating point rounding that surprises people in every language.
What is a nibble?
Half a byte, which is four bits, and the reason hexadecimal and binary pair so neatly: one hex digit is exactly one nibble, so 0xF is 1111 and 0xDE is 1101 1110 with no arithmetic needed. That is why the bit view on this page groups bits in fours and prints the hex value under each byte. Once you can read the sixteen nibble patterns, converting between hex and binary is lookup rather than calculation, which is not true of any other pair of bases in common use.
How do I tell whether one flag bit is set?
Paste the value, pick the register width your documentation uses, and count from the right, because bit 0 is the rightmost bit. The index printed above each group of four bits saves the counting. If bit 6 of a 32-bit status word shows 1, that flag is on. In code the same check is a bitwise AND against a mask with only that bit set, such as value AND 64 for bit 6, or value AND (1 shifted left by 6) if you prefer to write the bit number rather than the mask.
Is hexadecimal case sensitive?
Not for the value. 0xff and 0xFF are the same number, and this page accepts either. Case can still matter around the edges: some file formats and checksum listings specify one case, string comparisons in code treat the two spellings as different text, and a few older assemblers expect uppercase. The outputs here print hex digits in uppercase because that is the more common convention in register documentation, and the prefix stays lowercase as it is written in source code.
Does the number I type get uploaded anywhere?
No. The parsing, the conversion and the bit view all run in your browser with JavaScript, nothing is sent to a server, and the value is never written into the address bar, so copying the link shares the tool rather than your data. That matters more than it sounds for this particular tool, because the numbers people convert are often taken straight out of a crash dump, a licence key or a device serial. You can also load the page once and keep using it with the network off.
Sources
- MDN, BigInt (the arbitrary precision integer type this page parses and prints with, including
toString(radix)). - MDN, Number.MAX_SAFE_INTEGER (the 9,007,199,254,740,991 limit quoted above, and why integers past it stop being exact).
- MDN, parseInt() (the radix argument, and the fact that it returns a float rather than an exact integer).
- Python documentation, int() (parsing with an explicit base, and the prefixes accepted with base 0).
- Two’s complement, the signed and unsigned ranges in the table and the leading-zero octal literal are defined in the IEEE arithmetic and C language standards; the spreadsheet conversion functions and the calculator modes described above are documented by their vendors, who can change the limits between versions, so confirm against the version you are running.
More tools
Hex shows up in more places than registers. A CSS colour is three hex bytes, and the colour converter turns them into RGB and HSL. A checksum is a long hex string, and the hash generator produces SHA-256 and friends in your browser. If the number arrived inside an encoded blob, the Base64 decoder unwraps it first.
Related tools
- Base64 Encode and Decode
Convert text to Base64 and back with full UTF-8 support, so accented letters, CJK and emoj…
- SHA-256 Hash Generator
Compute SHA-1, SHA-256, SHA-384 and SHA-512 hashes of text or a file with the browser's Web Crypto API.
- Color Converter (HEX, RGB, HSL)
Convert colors between HEX, RGB and HSL instantly, with a built-in color picker, live prev…
- JSON Formatter and Validator
Pretty-print or minify JSON in your browser with 2-space, 4-space or tab indentation.
Privacy: the parsing, the conversion and the bit view all run in your browser. The number you type is never sent to a server, never stored, and never written into the address bar, so a copied link carries the tool and not your value. The page keeps working with the network switched off once it has loaded.
