Skip to content
ToolBoxGeniehome

IEEE 754 Floating Point Converter

Developer Tools · Added

Type 0.1 and a runtime prints 0.1, which is not the number it is holding. What it holds is a value beginning 0.100000000000000005551, and running to fifty-five digits before it ends. This computes that expansion exactly — with arbitrary-precision integers rather than floating point — alongside the sign, exponent and significand bits it came from.

Also accepts e-notation, Infinity and NaN. Known as double, f64, JavaScript number, DOUBLE PRECISION.

Input is
Values worth looking at

Result

The value actually stored, in full

0.1000000000000000055511151231257827021181583404541015625

Printed by a runtime as 0.1 — the shortest decimal that round-trips to these same bits, which is not the same thing as the value.

Hex
3fb999999999999a
Class
Normal
Sign
+ (0)
Exponent
-4

stored as 1019, bias 1023

Step to the next value
1.3877787807814457e-17

one unit in the last place

Relative error
5.551e-17

against what you typed

The bits

Sign0
Exponent · 11 bits01111111011
Significand · 52 bits1001100110011001100110011001100110011001100110011010

How the bits become the number

Sign
positive
Exponent field
01111111011 = 1019
Minus the bias
1019 − 1023 = -4
Significand
1.1001100110011001100110011001100110011001100110011010
Next value up
0.10000000000000002
Next value down
0.09999999999999999

That difference, exactly

0.0000000000000000055511151231257827021181583404541015625

  • The exact value runs to 55 significant digits. Only 17 of them are needed to identify this float uniquely, which is why runtimes print the short form instead.

The exact value is computed with arbitrary-precision integers, not with floating point. Every finite float is a whole number times a power of two, and dividing by a power of two always terminates in decimal — so there is an exact answer, however long it runs. The 0.1 case is 55 digits, and it ends in 5, as every one of them must.

How to use the ieee 754 floating point converter

  1. 1Pick binary64 for a double, or binary32 for a C float.
  2. 2Type a decimal number, or switch the input mode and paste a hex or binary bit pattern instead.
  3. 3Read the exact stored value, and compare it with what a runtime would print.
  4. 4Use the preset buttons to jump to the values worth looking at — machine epsilon, the largest safe integer, the smallest subnormal.

Examples

The canonical example

Input
0.1 as a double
Result
Bits 3fb999999999999a, stored as 0.1000000000000000055511151231257827021181583404541015625

Fifty-five digits, ending in 5, as every such expansion must.

Where integers stop being exact

Input
9007199254740993 as a double
Result
Comes back as 9007199254740992 — an error of exactly 1

That is 2^53 + 1. Above 2^53 the gap between representable doubles is 2, so odd numbers are gone.

Reading a memory dump

Input
40490fdb as binary32 hex
Result
3.1415927410125732421875 — π, as far as a float can hold it

The exact expansion is what the register contains, not the 3.14159 anyone would print.

About the ieee 754 floating point converter

What the bits mean

A binary64 double is one sign bit, eleven exponent bits and fifty-two significand bits. The exponent is stored with a bias of 1023 added, so the field holds 1023 for an exponent of zero — that arrangement lets floats be compared as if they were integers, which is a genuine hardware convenience. The significand has an implicit leading 1 that is never stored, buying a fifty-third bit of precision for free, because a normalised binary number always starts with a 1.

Two exponent field values are reserved. All zeros means either zero or a subnormal, depending on whether the significand is empty. All ones means infinity if the significand is empty and NaN if it is not. That is why there are so many distinct NaN bit patterns: any non-zero significand with a full exponent qualifies, and some architectures use the spare bits to record where the NaN came from.

binary32 is the same structure at 8 and 23 bits, with a bias of 127. It holds about seven decimal digits against a double's fifteen to seventeen, which is why it survives in graphics and machine learning — half the memory and half the bandwidth, for precision that was never the limiting factor there.

Why runtimes print something other than the value

A language printing 0.1 for a double is not lying so much as answering a different question. The convention is to print the shortest decimal string that round-trips — the fewest digits that, read back, produce these exact bits. For the double nearest 0.1 that string is "0.1", because no other double is closer to that decimal.

This is enormously convenient and it hides the thing that causes bugs. Two doubles that print identically can differ in their last bit, and a comparison between them will fail while every log line insists they are the same. Seeing the full expansion is what makes that visible, and it is the main reason to reach for a tool like this rather than a print statement.

The errors that come out of all this

Three patterns account for most floating point bugs in ordinary code. The first is equality comparison: 0.1 + 0.2 does not equal 0.3, and no amount of rearranging makes it. The second is accumulation — adding a small value a million times drifts, because each addition rounds, and summing a large array left to right loses precision that pairwise or compensated summation would keep.

The third is catastrophic cancellation: subtracting two nearly equal numbers discards most of the significant bits, so the answer has far less precision than either input. The classic case is the quadratic formula, where one root can be computed with almost no accuracy unless the expression is rearranged to avoid the subtraction. Watching the exact values move through such a calculation is the fastest way to see why.

Frequently asked questions

Why can 0.1 not be stored exactly?
For the same reason a third cannot be written exactly in decimal. A binary fraction can only represent numbers whose denominator is a power of two, and a tenth is not one — in binary, 0.1 is 0.0001100110011… repeating forever. The format has 52 bits of significand, so it stores the nearest value it can and the rest is lost. Every base has this problem for some fractions; binary just has it for the ones humans use most.
Why is the exact value always a terminating decimal?
Because every finite float is a whole number times a power of two, and dividing by a power of two always terminates in decimal. Ten is divisible by two, so multiplying the numerator by five for each halving turns the fraction into something over a power of ten — which is just a decimal point in a different place. That is how this tool computes the expansion: with big integers and no rounding anywhere, which is why it is exact rather than merely precise.
What is a subnormal number?
A value below the smallest normal float, stored with a zero exponent field and no implicit leading 1 in the significand. Subnormals let the format degrade gradually towards zero instead of dropping off a cliff, which keeps the property that subtracting two unequal numbers never gives zero. The cost is precision — they shed significant bits as they get smaller — and on some processors subnormal arithmetic is dramatically slower, which is why numerical code sometimes flushes them to zero deliberately.
What is machine epsilon and why does it matter?
It is the gap between 1 and the next representable double, 2.22 × 10⁻¹⁶, and it is the standard yardstick for relative precision in the format. Its practical use is in comparisons: testing two floats for equality is almost always a bug, and the fix is to test whether they differ by less than some multiple of epsilon scaled to their magnitude. Scaled, because the absolute gap between neighbouring floats grows with the numbers — near 1,000,000 it is far larger than epsilon.
Should I use a decimal type instead?
For money, yes, essentially always. Binary floating point cannot represent 0.01 exactly, so accumulating currency in a double produces small errors that eventually surface as a total that is a cent out. Decimal types store base-ten digits and get this right, at the cost of speed. Binary floating point remains correct for measurement, physics and graphics, where the inputs were approximate to begin with and the hardware speed matters.