Float (IEEE-754) inspector

See exactly why 0.1 + 0.2 ≠ 0.3, bit by bit.

Sign (1 bit) Exponent (11 bits) Mantissa (52 bits)
Value actually stored
0.10000000000000000555

Exactly representable

Hex
0x3FB999999999999A
Sign
Positive
Exponent
1019 (biased) → 2^-4
Category
normal
Size
8 bytes

How it works

IEEE-754 stores a number as a sign, an exponent and a fraction — binary scientific notation. The value is reconstructed as:

value = (−1)^sign × 1.mantissa × 2^(exponent − bias) double: 1 sign + 11 exponent + 52 mantissa bits, bias 1023 single: 1 sign + 8 exponent + 23 mantissa bits, bias 127

Why 0.1 is not 0.1

In binary, 0.1 is the repeating fraction 0.0001100110011… Just as 1/3 has no exact decimal expansion, 1/10 has no exact binary one. The stored value is the nearest double, about 0.1000000000000000055511151231257827. Every arithmetic operation starts from that.

The implicit leading 1

Normalised numbers always have a leading 1 before the binary point, so it is not stored — you get 53 bits of precision from 52 stored bits. Subnormal numbers, where the exponent field is all zeros, drop that assumption to represent values closer to zero at reduced precision.

Integers are exact up to 2⁵³

Every integer up to 9,007,199,254,740,991 is representable exactly. Beyond that, consecutive integers start sharing a representation: 2⁵³ and 2⁵³+1 are the same double. This is why 64-bit database IDs must be sent as strings in JSON, and why BigInt exists.

Never compare floats with ==

Compare against a tolerance instead: Math.abs(a − b) < 1e-9. For money, do not use floats at all — store integer minor units (cents, pence) or use a decimal library.

NaN is not equal to itself

NaN === NaN is false, by specification — which is why Number.isNaN exists. There are also two zeros, +0 and −0, which compare equal but behave differently: 1/0 is Infinity and 1/−0 is −Infinity.