Fundamentals 11 min read

Why Does 0.1 + 0.2 Not Equal 0.3? A Deep Dive into IEEE‑754 Floating‑Point Precision

The article explains why adding 0.1 and 0.2 in JavaScript, Python or C produces 0.30000000000000004 instead of 0.3, by detailing binary floating‑point representation, IEEE‑754 encoding, exponent alignment, rounding rules, and shows C code that reveals the exact stored bits.

ITPUB
ITPUB
ITPUB
Why Does 0.1 + 0.2 Not Equal 0.3? A Deep Dive into IEEE‑754 Floating‑Point Precision

Floating‑point rounding error

Adding 0.1 and 0.2 in JavaScript, Python or C does not yield exactly 0.3 because decimal fractions like 0.1 cannot be represented precisely in binary floating‑point format; the result is 0.30000000000000004 (or a longer 57‑digit representation in C).

Binary representation of numbers

Integers are stored as fixed‑size binary values (16‑bit short, 32‑bit int, 64‑bit long). Floating‑point numbers follow the IEEE‑754 standard: a sign bit, an exponent (biased) and a mantissa. Single precision uses 32 bits (1‑8‑23), double precision uses 64 bits (1‑11‑52).

How 0.1 is encoded

In binary, 0.75 = 1.1 × 2⁻¹ can be represented exactly, but 0.1 cannot; it is approximated by the nearest binary fraction, resulting in a mantissa that is slightly larger than the true value. The exponent bias for double precision is 1023, so the stored exponent for 0.1 is 01111111011 (binary 1019), giving an actual exponent of –4.

Demonstrating the stored bits in C

The following C program prints the raw bits of two double variables initialized to 0.1, showing the exact IEEE‑754 pattern.

void printBits(size_t const size, void const * const ptr) {
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
    for (i = size-1; i >= 0; i--) {
        for (j = 7; j >= 0; j--) {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
    puts("");
}

double a = 0.1;
double b = 0.1;
printBits(sizeof(a), &a);
printBits(sizeof(b), &b);

The output confirms the 64‑bit pattern with a sign of 0, exponent 01111111011 and a mantissa beginning with 0x19999….

Why 0.1 + 0.2 still deviates

When adding two floating‑point numbers, the exponents must be aligned. The smaller exponent (0.1) is shifted right, causing loss of low‑order bits. After alignment, the mantissas are added, producing a 53‑bit sum that overflows the 52‑bit mantissa field, so the exponent is incremented and the mantissa is rounded (round‑to‑nearest even). This rounding yields the final binary value that prints as 0.30000000000000004.

Maximum representable values in JavaScript

JavaScript numbers are IEEE‑754 double precision. The largest safe integer is Number.MAX_SAFE_INTEGER (2⁵³‑1 ≈ 9e15). The largest finite value is Number.MAX_VALUE (≈1.79e308). Because integers are stored in the mantissa, JavaScript cannot represent all 64‑bit integer values exactly.

Practical implications

Only about 15 decimal digits of a double are reliable; digits beyond that may be incorrect. When precise decimal arithmetic is required (e.g., financial calculations or astronomical simulations), use rational arithmetic, arbitrary‑precision libraries, or store values as integers representing smallest units.

Comparing floating‑point numbers safely

Instead of direct equality, compare the absolute difference against a tiny epsilon. In ES6, Number.EPSILON provides a suitable default tolerance, e.g., Math.abs((0.1+0.2) - 0.3) < Number.EPSILON.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptCprecisionfloating-pointIEEE-754
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

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.