IEEE 754 Float Converter
Convert between decimal, hex, and binary for IEEE 754 single and double precision. Flip individual bits and see the exact decimal value the float actually stores.
8 digits
32 bits
Bit layout
Click any bit to flip it.
Stored value
Normal — the mantissa has an implicit leading 1.
0.100000001490116119384765625This is what the hardware holds. 0.1 is the shortest decimal that reads back as the same value, which is why it is what most languages print.
0x3DCCCCCD0 (+)123 stored, -4 effective50331657.450581e-90.0999999940.10000001How the value is assembled
+ 2-4 × 1.10011001100110011001101 (binary) = 0.100000001490116119384765625What the bits mean
An IEEE 754 float is three fields packed into one word: a sign bit, a biased exponent, and a mantissa. The value is reconstructed as sign × 2exponent × significand, where the significand is the mantissa field with an implicit leading 1 in front of it.
| Field | binary32 (float) | binary64 (double) |
|---|---|---|
| Sign | 1 bit | 1 bit |
| Exponent | 8 bits, bias 127 | 11 bits, bias 1023 |
| Mantissa | 23 bits stored, 24 effective | 52 bits stored, 53 effective |
| Decimal digits | about 7.2 | about 15.9 |
| Smallest normal | 1.175494e-38 | 2.225074e-308 |
| Largest finite | 3.402823e+38 | 1.797693e+308 |
The exponent is stored biased rather than as a signed integer so that the bit patterns of positive floats compare in the same order as the numbers themselves. That property is why you can sort positive floats with an integer comparison, and it is what the bias subtraction shown above is undoing.
Why 0.1 is not 0.1
A binary fraction can only express values whose denominator is a power of two. One tenth is not such a value, so it is stored as the nearest float that is. In binary32 that is exactly:
0.100000001490116119384765625
Every language prints 0.1 for this because that is the shortest decimal string that converts back to the same float, and printing the full expansion would be unhelpful in almost every context. But the stored value is the long one, and that difference is what accumulates when you add a tenth ten thousand times, or compare a computed result against a literal.
Enter any value above and the exact expansion is shown alongside the printed form. Values that are exact in binary — halves, quarters, and integers within range — show identical strings.
Where floats bite in embedded code
Accumulating a sum
Adding a small value to a large accumulator loses the low bits of the small value entirely, because the result has to be rounded to the accumulator's exponent. Summing a long series of similar magnitudes in a binary32 accumulator can drift by a surprising amount. Accumulating in binary64 and storing the result as binary32 is usually the cheapest fix; Kahan summation is the option when a double is not available.
Integer counters in floats
binary32 represents every integer exactly only up to 224, which is 16,777,216. Beyond that, consecutive integers start to share bit patterns, and incrementing by one stops changing the value at all above 225. A millisecond tick counter overflows this range in under five hours, so tick counts and timestamps belong in integers.
Subnormals and timing
Values below the smallest normal number are represented as subnormals, which some FPUs handle in microcode or trap to software. On a part where that is the case, a filter whose state decays toward zero can suddenly run orders of magnitude slower once it enters the subnormal range. Many toolchains offer a flush-to-zero mode for exactly this reason, and enabling it is usually the right call in a control loop.
Comparing results
The distance between adjacent floats grows with the exponent, so a fixed epsilon that is sensible near 1.0 is meaningless near 106. Scale the tolerance to the magnitude of the values being compared, or compare the number of representable values between them. The ULP figure shown above is that distance at whatever magnitude you are currently inspecting.
Reading a float out of memory
When you have four bytes from a memory dump or a protocol capture rather than a number, paste them into the hexadecimal field. The usual complication is byte order: a little-endian device stores 123.456 as79 E9 F6 42 in memory, which is the reverse of the 42 F6 E9 79 the standard describes. If a value decodes to an absurd exponent, reversing the bytes is the first thing to try.
For values arriving over Modbus, the word order is a separate question again, and theModbus register decoder covers all four conventions devices use.
Special values
Two exponent patterns are reserved. All zeros means either zero or a subnormal, depending on the mantissa. All ones means infinity when the mantissa is zero, and NaN otherwise — the remaining mantissa bits are a payload that hardware and libraries use to distinguish quiet from signalling NaNs. Flipping the exponent bits above shows each of these directly.
Frequently asked questions
Why does 0.1 not stay 0.1?
A binary float can only represent fractions whose denominator is a power of two, and one tenth is not one of them. The nearest binary32 value is exactly 0.100000001490116119384765625. Languages print 0.1 because that is the shortest decimal that reads back as the same float, but the stored value is the longer one.
How many decimal digits does a float actually hold?
binary32 carries 24 bits of significand, which is about 7.2 decimal digits; binary64 carries 53 bits, about 15.9 digits. In practice, round-tripping through text needs 9 digits for binary32 and 17 for binary64 to guarantee the exact same value comes back.
What is a subnormal number?
When the exponent field is all zeros, the implicit leading 1 of the mantissa is dropped and the exponent is fixed at its smallest value. That lets values continue below the smallest normal number, trading precision for range as they approach zero. Some embedded FPUs handle subnormals in software, or flush them to zero, which can cause a large and surprising timing spike.
Why are there two zeros?
The sign bit is independent of the rest of the encoding, so +0 and -0 have different bit patterns. They compare as equal under ==, which means a sign check on a zero result has to inspect the bit pattern or use a function like signbit().
Can I compare floats for equality?
Only when you know both sides came from the same computation. Otherwise compare against a tolerance, and choose that tolerance relative to the magnitude of the values rather than as a fixed constant — the gap between adjacent floats grows with the exponent, as the ULP figure above shows.
Which integers are exact in a float?
Every integer up to 2^24 (16,777,216) is exact in binary32, and up to 2^53 in binary64. Above that, consecutive integers start sharing a representation. A 32-bit counter or timestamp stored in a binary32 float will silently lose its low bits.