IEEE 754 float and hex, decoded field by field

Published 11 September 2026 · Updated 11 September 2026 · 11 min read

Sine-wave illustration
Single- and double-precision bit patterns, decoded into sign, exponent and mantissa.

Sooner or later a float arrives as four bytes on a wire and you have to say what number it represents. A logic analyser capture, a Modbus register pair, a sensor frame, a binary log file — none of them carry a decimal point. What they carry is a bit pattern, and IEEE 754 defines exactly what that pattern means: one sign bit, a biased exponent, and a fraction with an implied leading one.

The converter below shows every field of the pattern while you edit either side, so you can check the arithmetic rather than trust it.

IEEE 754 float ↔ hex / binary converter

Edit the number or the bit pattern — either side updates the other. Use e.g. 0.1, -6.5, Infinity or NaN.

Spaces and underscores are ignored. A 32-bit pattern must be 8 hex digits or 32 binary digits — a short pattern is rejected rather than zero-padded.
Hex
Binary (sign | exponent | mantissa)
Sign
Exponent (biased)
Exponent (unbiased)
Mantissa (fraction)
Class
Value stored
Storage error (typed − stored)
Spacing (ULP)
Rebuilt from the fields

The last row recomputes the value from the decoded fields using the definition below, instead of reading it out of memory. When the two agree, the field boundaries have been read correctly — which is the actual question a capture raises.

The three fields

A binary32 value is 32 bits laid out as one sign bit, eight exponent bits and twenty-three mantissa bits. Read as a whole it looks arbitrary; read in three pieces it is straightforward.

value = (−1)sign × 2(exponent − 127) × (1 + mantissa / 223)
  • Sign — 0 is positive, 1 is negative. There is no two's complement trickery here; the sign is a separate magnitude bit, which is why −0.0 and +0.0 both exist.
  • Exponent — stored biased by 127, so the raw field 127 means 20. The bias lets a small unsigned field cover both very large and very small magnitudes.
  • Mantissa — the fraction after the binary point. The leading 1 is not stored; it is implied for every normal number. That free bit is where the extra precision comes from, and it is also why the subnormal range has to be defined separately.

What the extreme exponent values mean

The exponent field all-zero and all-one are reserved, so the encoding does not follow the formula above for them.

Exponent fieldMantissaMeaning
00Signed zero, +0.0 or −0.0
0non-zeroSubnormal: value = (−1)s × 2−126 × (0 + mantissa/223) — the implicit leading 1 is gone, so precision degrades as the value shrinks
1–254anyNormal, per the formula above
2550Infinity, with the sign bit applying
255non-zeroNaN. The payload is unspecified, and a signalling NaN is any NaN with the leading mantissa bit clear

Reading −6.5 by hand

6.5 is 110.1 in binary. Normalise by moving the point two places left, so it becomes 1.101 × 22. From there the fields follow directly:

  • Exponent: 2 + 127 = 129, which is 10000001.
  • Mantissa: the fraction 101 padded to 23 bits with zeros, which is 0.625 as a fraction.
  • Sign: negative, so 1.

Concatenating gives 1 10000001 10100000000000000000000, which is 0xC0D00000. Drop the sign bit and the same pattern becomes 0x40D00000 for +6.5. Check it in the converter: the exponent row reads 129 and the unbiased row reads 2, and the rebuilt value matches.

Why 0.1 does not survive

0.1 has no exact binary representation, exactly as 1/3 has no exact decimal one. Cast it to binary32 and the nearest representable value is 0x3DCCCCCD, which is 0.100000001490116 when read back. The error is 1.49×10−9, about 0.2 of one step at that magnitude.

That "one step" is the ULP, the distance between adjacent representable numbers. At 1.0 a binary32 ULP is 2−23 ≈ 1.19×10−7; at 0.1 it is 2−27 ≈ 7.45×10−9, because 0.1 sits in the binade below 2−3. The converter prints the ULP alongside the value for this reason: rounding error in a report only means something when compared with the spacing at that magnitude, not with the decimal digits.

A related consequence is integer precision. The largest binary32 integer that survives an increment is 224 = 16777216; add one and you get 16777216 back, because the ULP up there is 2. Counters, sample indices and timestamp accumulators are where this bites hardest.

Five mistakes that survive in production code

  1. Ignoring byte order. 0x3F800000 on the wire is often transmitted 00 00 80 3F. The bit pattern is defined by the standard; the byte order is defined by the protocol. Decode the hex, then worry about the endianness of the four bytes that delivered it.
  2. Using 8 hex digits where 16 are needed. A binary64 value needs 16. Reading eight digits of a double pattern, or zero-padding eight digits up to sixteen, quietly turns 1.0 into a subnormal near 4.9×10−315. That is why the converter refuses a pattern of the wrong width instead of padding it.
  3. Comparing floats for equality. After a conversion or a few arithmetic operations, exact equality is a coin flip. Compare the absolute difference against a stated tolerance, and make that tolerance a multiple of the ULP rather than a decimal guess.
  4. Treating the exponent field as a plain number. A raw exponent of 255 does not mean 2128; it means infinity or NaN, and code that computes with it before checking will propagate a NaN through everything downstream.
  5. Assuming −0.0 is just 0.0. It is a different bit pattern (0x80000000 versus 0x00000000) and it compares equal to zero, so a checksum or a bit-exactness test will disagree with an equality test. Decide which one you meant.

Single and double differ only in width

Binary64 uses the same three fields with 11 exponent bits, 52 mantissa bits and a bias of 1023. 1.0 is 0x3F800000 as a float and 0x3FF0000000000000 as a double, and the two patterns encode the same value with different precision. Everything above about subnormals, infinities and NaN applies unchanged; only the constants move, from 127 to 1023 and from 2−126 to 2−1022.

Constants worth committing to memory

binary32 patternValue
0x00000000+0.0
0x80000000−0.0
0x00000001Smallest positive subnormal, 1.4012984643×10−45
0x00800000Smallest positive normal, 2−126 ≈ 1.1754943508×10−38
0x3DCCCCCD0.1, rounded to nearest
0x3F800000+1.0
0xBF800000−1.0
0x40D00000+6.5
0xC0D00000−6.5
0x7F7FFFFFLargest finite value, 3.4028234664×1038
0x7F800000+Infinity
0xFF800000−Infinity
0x7FC00000Quiet NaN, the canonical one

Summary

Split the pattern into sign, exponent and mantissa, remember that the exponent is biased and the leading mantissa bit is implied, and handle the two reserved exponent values before doing any arithmetic. Convert through the bit pattern rather than through decimal text, and let the tool above show you the fields whenever a capture looks wrong.

One last practical note: the converter's "value stored" row is what the receiving device will compute from those bits, which is not always what the transmitting code intended. Values shown are engineering aids rather than measurements; see the disclaimer. Other converters are listed in the tool index.