The IEEE 754 Floating-Point Reference combines a static format table with a
live bit decoder. Type any number and it shows the exact single- and
double-precision bit patterns the way your CPU actually stores them — so you can
see why 0.1 is not really 0.1 and where the sign, exponent and mantissa bits
land in binary32 and binary64.
How it works
IEEE 754 binary formats all share the same structure: one sign bit, a fixed-width exponent field stored with a bias, and a mantissa (also called the significand or fraction). For a normal number the value is:
value = (-1)^sign × 1.mantissa × 2^(exponent − bias)
The leading 1. is implicit (the “hidden bit”) in every format except the x87
80-bit extended, which stores it explicitly. The bias makes the stored exponent
unsigned: it is 2^(expBits-1) − 1, giving 127 for single precision and 1023
for double. Two exponent patterns are special:
exponent = 0 → ±0 (mantissa 0) or subnormal numbers (mantissa ≠ 0)
exponent = all 1s → ±Infinity (mantissa 0) or NaN (mantissa ≠ 0)
The decoder writes your number into an ArrayBuffer with DataView.setFloat32 /
setFloat64, then reads back the raw integer bytes — so the bits shown are the
genuine stored representation, including rounding, not an approximation.
Format comparison table
| Format | Total bits | Sign | Exponent bits | Mantissa bits | Bias | Approx. decimal digits | Max value |
|---|---|---|---|---|---|---|---|
| Half (binary16) | 16 | 1 | 5 | 10 | 15 | ~3.3 | ~65504 |
| Single (binary32) | 32 | 1 | 8 | 23 | 127 | ~7.2 | ~3.4 × 10³⁸ |
| Double (binary64) | 64 | 1 | 11 | 52 | 1023 | ~15.9 | ~1.8 × 10³⁰⁸ |
| Quad (binary128) | 128 | 1 | 15 | 112 | 16383 | ~34.0 | ~1.2 × 10⁴⁹³² |
| x87 Extended (80-bit) | 80 | 1 | 15 | 64 | 16383 | ~18.5 | ~1.2 × 10⁴⁹³² |
The x87 80-bit extended format is notable for explicitly storing the leading bit of the significand (the “integer bit”), unlike every other format where it is implied. This made it the favored format for intermediate FPU calculations on x86 processors for decades.
Worked example and the 0.1 problem
Decode 0.1 and the single-precision mantissa shows a repeating ...11001100 pattern: 0.1 cannot be stored exactly in binary, just as 1/3 cannot be stored exactly in decimal. The CPU rounds to the nearest representable value, which is why 0.1 + 0.2 !== 0.3 in most programming languages — the rounding errors accumulate differently from how they would cancel.
The decoder here shows the genuine stored bits from a DataView.setFloat32/setFloat64 call, so the stored value it reports is exactly what your language’s runtime holds when it evaluates a float or double literal.
Where each format is used
- binary16 (half) — GPU shaders, machine learning inference (fp16), HDR image storage. Half the bandwidth of single-precision with a useful dynamic range.
- binary32 (single, C
float) — Graphics pipelines, physics simulations, most embedded and mobile compute where memory bandwidth matters more than precision. - binary64 (double, JavaScript
Number, Pythonfloat) — General-purpose computation, financial math (though integers are safer), scientific calculation. - binary128 (quad) — High-precision library functions, verification of double-precision results. Not hardware-native on most CPUs; emulated in software.
- x87 80-bit — Legacy x86 FPU intermediate calculations. Largely displaced by SSE/AVX double-precision for new code, but still relevant when debugging x87-generated results that differ from SSE results due to the extra mantissa bits.
Reading the bit decoder output
The decoder shows the biased exponent (the raw stored value) and the unbiased exponent (the true power of two). For single precision: unbiased = stored − 127. A stored exponent of 0 signals a zero or subnormal; a stored exponent of 255 signals infinity or NaN. Everything else is a normal number, and the value is reconstructed as 1.mantissa × 2^(unbiased exponent).