Ask almost any programming language to calculate 0.1 + 0.2, and it will return 0.30000000000000004. This is not a software bug, but a mathematical consequence of the IEEE 754 floating-point standard. Because computers store fractional numbers in binary base-2, fractions like 1/10 produce infinitely repeating sequences—much like 1/3 in decimal. Rounding these infinite binary decimals creates slight precision errors in everyday arithmetic.
The mystery of 0.1 + 0.2
Open a terminal, launch almost any standard programming language—such as Python, JavaScript, C, or Java—and ask the computer to calculate 0.1 + 0.2. Instead of returning the clean decimal 0.3 that any elementary school child would expect, the system will output 0.30000000000000004. This peculiar discrepancy is often a programmer's first encounter with the boundaries of computer arithmetic. Because computers are celebrated for their speed and mathematical exactness, producing an incorrect answer for basic addition can feel like an alarming software defect.
However, this behavior is not a bug in the code, a hardware flaw, or an oversight by language designers. It is the natural mathematical result of representing real numbers inside finite physical memory using the binary numeral system. Modern computer hardware handles fractional numbers using an international standard known as IEEE 754 floating-point arithmetic. To understand why this standard behaves this way, one must examine how numbers are translated from human base-10 notation into computer base-2 notation.
Base 10 vs. Base 2
In everyday base-10 mathematics, place values represent powers of ten: tenths, hundredths, thousandths, and so on. A fraction can be written as a finite, terminating decimal if and only if its denominator's prime factors are exclusively 2 and 5, which are the prime factors of the base 10. For example, 1/2 is 0.5, 1/4 is 0.25, and 1/5 is 0.2. Conversely, a fraction like 1/3 cannot be expressed as a finite decimal because 3 does not divide evenly into any power of 10. It becomes an infinitely repeating sequence: 0.33333...
Computers do not count in base 10; they store and process data using binary, or base 2. In binary, place values represent powers of two: halves (1/2), quarters (1/4), eighths (1/8), sixteenths (1/16), and so forth. A fraction has a terminating representation in binary only if its denominator is a power of two. The fraction 1/10 (0.1 in decimal) has a denominator with a prime factor of 5. Because 5 cannot be built purely from powers of 2, 1/10 becomes an infinitely repeating fraction in binary: 0.0001100110011... repeating forever.
Just as base-10 paper cannot record the infinite digits of 1/3 without stopping somewhere, binary hardware cannot store the infinite sequence of 1/10 without cutting it off. The computer must round the value to fit inside a predetermined number of binary digits.
How IEEE 754 stores numbers
The IEEE 754 standard specifies how computers encode fractional numbers into bits. The most widespread format is double-precision floating-point, commonly referred to as binary64. A double-precision number occupies 64 bits of memory, divided into three distinct components: 1 bit for the sign (positive or negative), 11 bits for the exponent (which sets the scale or magnitude), and 52 bits for the fraction, also known as the mantissa or significand.
Because normalized numbers in binary always start with a leading 1, hardware implementations do not waste a bit storing that leading digit. This gives the significand 53 bits of effective precision. When an infinitely repeating binary fraction like 0.1 is converted into binary, it must be rounded to fit within these 53 bits. The standard specifies default rounding rules, most commonly rounding to the nearest representable value, with ties broken by choosing the even binary number.
As a result of this rounding, the exact value stored in memory for 0.1 is not precisely 1/10. It is a nearby rational number whose numerator and denominator depend on powers of two: specifically 3602879701896397 divided by 2 to the power of 55. In decimal, this stored value is approximately 0.1000000000000000055511151231257827021181583404541015625. Similarly, 0.2 is stored as slightly more than 2/10. Neither number is exact at the moment of entry.
Accumulating precision errors
When a program executes the addition 0.1 + 0.2, the central processing unit does not perform arithmetic on the original human values 0.1 and 0.2. Instead, it adds the two slightly imprecise binary numbers already resting in its registers. The true mathematical sum of those two stored values is approximately 0.3000000000000000444089209850062616169452667236328125.
This sum must once again be rounded to fit into 53 bits of binary significand. The nearest representable IEEE 754 double-precision number to that intermediate sum turns out to be slightly larger than the true decimal 0.3. When the programming language converts this stored binary result back into human-readable text, it prints the shortest decimal string that uniquely identifies that exact binary number, which yields the familiar output: 0.30000000000000004.
This error is extremely small—on the order of a few parts in sixteen quadrillion. In everyday casual calculations, graphics rendering, and many physical simulations, an error of this magnitude is entirely imperceptible and harmless. However, when multiple floating-point operations are chained together in long algorithms, these tiny truncation and rounding differences can accumulate, shift results, or create unexpected behavior during direct equality checks.
Why display formats can deceive
A common point of confusion is why entering simply 0.1 into an interactive prompt often outputs 0.1, whereas adding 0.1 + 0.2 produces a visible tail of digits. This difference comes down to how languages format numbers for human consumption. Modern runtime environments use algorithms designed to produce the shortest decimal representation that rounds back to the exact same internal binary number.
For a single value like 0.1, the shortest unique decimal representation is simply '0.1', because no other nearby double-precision binary number is closer to 0.1 than the one stored. The display logic neatly masks the underlying binary approximation. But when two rounded values are added together, the resulting binary bit pattern lands on a point on the number line whose shortest unique decimal identifier requires displaying the trailing 4. The underlying approximation is not newly created by addition; it is merely unmasked.
Practical strategies for exact computing
Because floating-point numbers represent approximations of real numbers, software developers must use specific strategies when exactness is mandatory. A standard rule of thumb is never to compare two floating-point numbers using strict equality operators. Instead of checking whether a + b == c, reliable code checks whether the absolute difference between the two values is smaller than a tiny predefined tolerance threshold, often called epsilon.
In financial calculations, where rounding errors can lead to legal and accounting issues, standard binary floating-point types are deliberately avoided. Systems handling currency often store values as integers representing the smallest unit (such as cents instead of whole dollars) or utilize dedicated decimal arithmetic libraries, such as Python's decimal module. Decimal data types store base-10 digits directly in memory, eliminating the conversion mismatch for numbers like 0.1 at the cost of slower execution speeds compared to hardware-accelerated IEEE 754 binary arithmetic.
Key takeaways
•Fractions like 0.1 (1/10) cannot be represented finitely in binary base-2, creating infinitely repeating sequences analogous to 1/3 in decimal.
•The IEEE 754 double-precision standard allocates 53 effective bits to a number's significand, forcing infinite binary fractions to be rounded to the nearest representable value.
•The result 0.30000000000000004 occurs because computers add the rounded binary approximations of 0.1 and 0.2, not the exact decimal values.
•Systems requiring strict accuracy, such as financial applications, avoid binary floating-point in favor of integer units or dedicated base-10 decimal formats.