floating-point rounding and why 0.1 is not exact
Type 0.1 + 0.2 into almost any programming language and ask for the result, and you will often get not 0.3 but 0.30000000000000004. This is not a bug in the language and not a flaw in your computer — it is an unavoidable consequence of storing decimal fractions in binary with a fixed number of bits. Understanding why turns a baffling surprise into an expected, manageable fact of life.
The heart of it: a float stores numbers in BINARY, and just as 1/3 cannot be written exactly in decimal (0.3333... forever), the value 0.1 cannot be written exactly in binary. In base two, 0.1 is the repeating fraction 0.0001100110011... with no end. Since only a fixed number of mantissa bits are available, the computer stores the NEAREST representable value, which is a hair off from true 0.1. Do arithmetic on these slightly-off values and the tiny errors can add up or reveal themselves, which is exactly how 0.1 + 0.2 lands a few quadrillionths away from 0.3. Whenever a result cannot be represented exactly, IEEE-754 ROUNDS it to a representable neighbour, by default to the nearest one (ties going to the value with an even last bit, called round-half-to-even).
The practical lessons are concrete. Never test floats for exact equality; compare within a small tolerance suited to your problem. Be aware that rounding errors can accumulate over long computations, so the ORDER of operations can change the result slightly. And for values that truly must be exact — money above all — do not use binary floating point at all; use integer cents, a fixed-point representation, or a decimal type. Floating point is the right tool for measured and continuous quantities, where being correct to fifteen digits is plenty; it is the wrong tool when 'off by a penny' is unacceptable.
In binary, 0.1 is 0.0001100110011... repeating forever, so it is stored rounded. That is why 0.1 + 0.2 yields 0.30000000000000004, and why money should use integer cents, not a double.
0.1 is non-terminating in binary, so it is stored as the nearest value.
The error is in the binary REPRESENTATION, not the addition: 0.1 and 0.2 are already slightly wrong the instant you write them, so even storing 0.1 alone is inexact. Exactness for money or counts needs integers or a decimal type.