The floating point converter above shows exactly how a number is stored in IEEE 754 binary formats. For half, single and double precision it splits the encoding into its sign bit, its exponent field and its mantissa, gives the raw hexadecimal pattern, and prints the exact decimal value the machine is actually holding — which is very often not the value you typed. It also reports the absolute and relative error introduced by that rounding. Everything runs locally in your browser.
Arb Digital publishes this alongside its other free developer tools because floating-point surprises cause a specific and recurring class of bug: totals that end in a stray 0.0000000000004, comparisons that fail when the two sides look identical on screen, and money calculations that drift by a cent over thousands of rows. Seeing the bits makes the cause obvious in a way that reading about it never quite does.
What This Floating Point Converter Does
Every IEEE 754 binary format packs three fields into a fixed number of bits. Double precision, called binary64, uses one sign bit, eleven exponent bits and fifty-two mantissa bits. Single precision, binary32, uses one, eight and twenty-three. Half precision, binary16, uses one, five and ten. The value represented is the sign applied to the mantissa — interpreted with an implied leading 1 for normal numbers — multiplied by two raised to the unbiased exponent.
The tool converts in both directions. Give it a decimal number and it produces the bit pattern for all three formats. Give it a raw hexadecimal pattern from a memory dump, a network capture or a log file and it decodes the number that pattern represents. It also handles the special encodings: signed zeros, infinities, and the quiet and signalling NaN patterns that appear when a calculation has gone wrong upstream.
A neighbouring tool with a different job: the number base converter handles integers between binary, octal, decimal and hexadecimal. Integers are exact in every base, so nothing is lost there. This page exists precisely because fractions in binary usually are not.
How to Use It
- Type a decimal number. Scientific notation works, and so do Infinity and NaN if you want to see those encodings.
- Read the exact stored value first. If it differs from what you typed, the difference is the rounding error — not a display artefact.
- Compare the three precisions. The same number rounds differently in each, and half precision often rounds visibly enough to matter.
- Switch the input type to decode a bit pattern. Paste sixteen hex digits for a double or eight for a single.
- Raise the digit count if the exact value is truncated. A double's exact decimal expansion can run to more than 750 digits for very small numbers.
The Encoding and How It's Calculated
For a normal number the value is:
value = (−1)sign × (1 + mantissa ÷ 2p) × 2(exponent − bias)
where p is the number of mantissa bits and the bias is 1023 for double precision, 127 for single and 15 for half. Take the number 1.0 in double precision. The sign bit is 0, the stored exponent is 1023 so the unbiased exponent is 0, and the mantissa field is all zeros, representing the implied 1 exactly. The bit pattern is 0x3FF0000000000000.
Now take 0.1. In binary, one tenth is the recurring fraction 0.0001100110011001100... repeating forever, exactly as one third is 0.333... recurring in decimal. It cannot be written in a finite number of binary digits, so the format stores the nearest representable value instead. That value is 0.1000000000000000055511151231257827021181583404541015625, and the bit pattern is 0x3FB999999999999A — note the final A, which is the rounding-up of a run of nines. The stored number is larger than one tenth by about 5.55 × 10−18.
When the stored exponent field is all zeros the number is subnormal: the implied leading 1 becomes a leading 0 and the exponent is fixed at the minimum, which lets the format represent values closer to zero at the cost of precision. When the exponent field is all ones the value is infinity if the mantissa is zero and NaN otherwise. These rules are defined in IEEE 754-2019, the IEEE Standard for Floating-Point Arithmetic, which specifies the interchange formats, the arithmetic and the exception behaviour that every mainstream language and processor implements.
Why 0.1 Is Not 0.1, and Why 0.1 + 0.2 Is Not 0.3
This is the section worth reading carefully, because the usual explanation — “floating point is imprecise” — is wrong in a way that makes the behaviour seem random when it is completely deterministic.
A binary fraction can only represent numbers whose denominator is a power of two. One half, one quarter, three eighths and 2.5 are all exact in binary and always will be. One tenth is not, because 10 has a factor of 5, and no power of two is divisible by 5. The same thing happens in decimal with one third: 0.333... never terminates, not because decimal is sloppy but because 3 does not divide any power of 10. Binary is exact; it is just exact about a different set of numbers than the ones we write down.
So when you write 0.1 in source code, the compiler stores the nearest double, which is very slightly greater than one tenth. When you write 0.2, it stores the nearest double to two tenths, which is also very slightly greater. Adding those two stored values gives a sum that is not the nearest double to 0.3, so the result prints as 0.30000000000000004. Every step is exactly specified and perfectly repeatable. There is no randomness anywhere in it — run it on any conforming platform and you get the identical digits.
Two consequences follow. First, never compare floating-point values with equality; compare the absolute difference against a tolerance appropriate to the magnitudes involved. Second, never store money as a binary float. Use integer minor units — cents, pence, paise — or a decimal type whose base is 10, so that 0.01 is exact. The classic treatment of all of this is David Goldberg's What Every Computer Scientist Should Know About Floating-Point Arithmetic, reprinted as an appendix to the Oracle Numerical Computation Guide, which works through rounding error, cancellation and guard digits in full.
Precision Limits You Can Actually Rely On
Double precision gives roughly 15 to 17 significant decimal digits: any 15-digit decimal round-trips through a double unchanged, and 17 digits are always enough to reproduce a double exactly. Single precision gives 6 to 9 digits, and half precision only 3 to 4. That is why a single-precision float is a poor choice for accumulating a long sum of similar-sized values, and why half precision is used for machine-learning weights, where the tolerance for error is high, rather than for arithmetic where it is not.
Integers have a harder boundary. A double represents every integer exactly up to 253, which is 9,007,199,254,740,992. Above that, consecutive integers start to share representations: 253 + 1 is not representable and rounds to 253. This is the reason 64-bit identifiers from a database or an API break when they pass through JSON in a JavaScript environment — the number survives the wire perfectly and is mangled on parse. Transmit such identifiers as strings. For single precision the same limit is 224, only 16,777,216, which is low enough that ordinary counters reach it.
Where the Error Actually Comes From
Representation error, the kind shown in the hero box above, is usually the smallest of your problems. Three other effects do more damage. Accumulation is the first: add a small number to a large one repeatedly and each addition rounds away part of the small value, so summing a million values of 0.1 drifts noticeably from 100,000. Summing smallest-first, or using a compensated summation algorithm, largely fixes it.
Cancellation is the second and the worst. Subtracting two nearly equal numbers destroys the leading digits they had in common and promotes the rounding noise in the trailing digits to being the whole answer. A quadratic formula implemented naively loses most of its precision this way when the discriminant is close to the square of the coefficient. Reformulating the expression, rather than adding more precision, is the fix.
Order dependence is the third and the most surprising: floating-point addition is not associative, so (a + b) + c and a + (b + c) can give genuinely different results. That is why a parallel sum can disagree with a serial one, and why two runs of the same aggregation with different thread scheduling can return different totals. For the integer and bit-level side of this work, the bitwise calculator, the two's complement converter and the binary arithmetic calculator cover representations where none of these effects exist, and the percent error calculator is useful for quantifying the drift you do find.
Arb Digital builds websites and web applications with money handled in integer minor units and totals that reconcile to the cent.
See Web Design Services Talk to Arb DigitalCommon Mistakes to Avoid
- Comparing floats with equality. Two values that display identically can differ in the last bit. Compare the difference against a tolerance scaled to the magnitudes involved.
- Storing money in a binary float. Use integer minor units or a decimal type. Binary cannot represent 0.01 exactly, so cents drift as rows accumulate.
- Passing 64-bit identifiers through a double. Anything above 253 loses its last digits silently. Send such identifiers as strings.
- Rounding for display and assuming the stored value changed. Formatting to two decimals hides the error; it does not remove it from the value you are still calculating with.
- Blaming the language. The behaviour is specified by IEEE 754 and is identical across conforming platforms. The bug is in the expectation, not the runtime.
Related Free Tools From Arb Digital
For integer conversions there is the number base converter, and for signed integer encoding the two's complement converter. The bitwise calculator and binary arithmetic calculator handle bit-level operations. Very large and very small magnitudes are easier to read through the scientific notation converter, general arithmetic is in the scientific calculator, and the percent error calculator quantifies the difference between a stored and an intended value. Everything else is in the free online tools hub.
Frequently Asked Questions
Because binary fractions can only represent numbers whose denominator is a power of two, and one tenth is not one of them. The nearest double is 0.1000000000000000055511151231257827021181583404541015625, which is what actually gets stored.
Both values are stored as the nearest doubles, each slightly larger than the decimal fraction you wrote. Their sum is not the nearest double to 0.3, so the printed result differs in the seventeenth significant digit. The behaviour is fully deterministic.
Between 15 and 17 significant digits. Any 15-digit decimal survives a round trip unchanged, and 17 digits are always enough to reconstruct a double exactly. Single precision gives 6 to 9, and half precision only 3 to 4.
2 to the power 53, which is 9,007,199,254,740,992. Above that, consecutive integers start sharing representations, which is why 64-bit database identifiers should be transmitted as strings rather than numbers.
When the exponent field is all zeros, the implied leading 1 becomes a leading 0 and the exponent is fixed at its minimum. This lets the format represent values closer to zero than the smallest normal number, with progressively fewer significant bits.
The sign bit is independent of the magnitude, so both positive and negative zero exist and compare as equal. An exponent field of all ones means infinity when the mantissa is zero and NaN otherwise, which gives a large number of distinct NaN bit patterns.
Compare the absolute difference against a tolerance chosen for the magnitudes involved, or compare the number of representable values between them. Direct equality only works reliably for values that are exact in binary, such as halves and quarters.
No. The conversion runs in your browser as local JavaScript. The page makes no network request, stores nothing and logs nothing, so the values you enter never leave your device.