Fundamentals 7 min read

Understanding Floating-Point Precision Issues in JavaScript (0.1+0.2 vs 0.3+0.4)

JavaScript’s unexpected result for 0.1 + 0.2 versus the exact 0.3 + 0.4 arises because numbers are stored in IEEE‑754 double‑precision binary, where limited mantissa bits require exponent alignment and rounding (ties‑to‑even), causing small representation errors that appear as 0.30000000000000004.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Understanding Floating-Point Precision Issues in JavaScript (0.1+0.2 vs 0.3+0.4)

When performing arithmetic in JavaScript, expressions such as 0.1+0.2 produce 0.30000000000000004 , while 0.3+0.4 yields the exact 0.7 . This article explains why, based on the binary representation of floating‑point numbers and the rounding rules defined by the IEEE‑754 standard.

1. Binary storage of floating‑point numbers

JavaScript follows the IEEE‑754 double‑precision (64‑bit) format. The 64 bits are divided as:

Bit 0 – sign (0 for positive, 1 for negative)

Bits 1‑11 – exponent

Bits 12‑63 – fraction (mantissa). The leading 1 is implicit, so the stored mantissa has 52 bits, giving 53 bits of precision.

Example binary forms of 0.1 , 0.2 , 0.3 , 0.4 and 0.7 are shown below:

0.1 -> 0.0001100110011… (repeating) → 0‑01111111011‑ (1.)1001100110011001100110011001100110011001100110011010 (rounded)
0.2 -> 0.001100110011… → 0‑01111111100‑ (1.)1001100110011001100110011001100110011001100110011010 (rounded)
0.3 -> 0.01001100110011… → 0‑01111111101‑ (1.)0011001100110011001100110011001100110011001100110011 (rounded)
0.4 -> 0.01100110011… → 0‑01111111101‑ (1.)1001100110011001100110011001100110011001100110011010 (rounded)
0.7 -> 0.101100110011… → 0‑01111111110‑ (1.)0110011001100110011001100110011001100110011001100110 (rounded)

After the 52‑bit mantissa, rounding (0‑to‑1) occurs, causing precision loss.

2. Alignment (对阶) before addition

Because the exponents differ, operands must be aligned. The aligned sums are:

0.1 + 0.2 → 10.0110011001100110011001100110011001100110011001100111
0.3 + 0.4 → 10.1100110011001100110011001100110011001100110011001101

After normalization, low‑order bits are discarded and rounded:

0.1 + 0.2 → 1.00110011001100110011001100110011001100110011001100111‑ → 1.0011001100110011001100110011001100110011001100110100 (rounded up)
0.3 + 0.4 → 1.01100110011001100110011001100110011001100110011001101‑ → 1.0110011001100110011001100110011001100110011001100110 (rounded down)

The result of 0.1+0.2 differs from the stored mantissa of 0.3 , leading to the observed 0.30000000000000004 , while 0.3+0.4 matches the mantissa of 0.7 .

3. IEEE‑754 rounding rules (ties‑to‑even)

IEEE‑754 uses “round to nearest, ties to even”. When the bits beyond the retained precision are exactly halfway, the result is rounded to the nearest even least‑significant bit. The process involves three bits:

Round bit (the first discarded bit)

Sticky bit (OR of all remaining discarded bits)

Least‑significant retained bit

If the sticky bit is 1, the round bit decides a 0‑to‑1 increment; if the sticky bit is 0 and the round bit is 1, the result is rounded to the nearest even value.

4. Summary

The precision anomalies are not specific to JavaScript; any language that implements IEEE‑754 double‑precision will exhibit the same behavior. In practice, developers can mitigate the issue by controlling the number of displayed digits or using arbitrary‑precision libraries.

JavaScriptprecisionfloating-pointieee754rounding
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.