On a laptop I added 0.1 a million times. It should make 100,000. In 32-bit numbers I got 100,958.34 (in 64-bit, 100,000.0000013).
A computer keeps every number in a fixed count of binary digits, so it can only land on certain values, like the marks on a ruler. One tenth isn't one of them: in binary it never ends (0.000110011001100...), the way a third never ends in decimal. So the machine keeps the nearest mark. In 64 binary digits that is 0.1000000000000000055511151231257827021181583404541015625, a hair too big. The same goes for 0.2, and their sum rounds to the mark just above 0.3.
In the 1960s and 70s every line of computers rounded in its own way. "Twenty years ago anarchy threatened floating-point arithmetic," William Kahan wrote in 1997. A draft by Kahan, Jerome Coonen and Harold Stone became IEEE 754, approved in 1985, and almost every computer has rounded the same way since. So it isn't a bug: every machine that follows the standard gets the same answer.
Fixed digits can matter. On 25 February 1991 a Patriot missile battery at Dhahran had been running for over 100 hours. Its clock counted tenths of a second and its time was worked out in 24-bit registers; by then it was off by 0.3433 seconds, it looked in the wrong place for an incoming Scud, and 28 American soldiers were killed (US GAO report IMTEC-92-26, 1992).
That's why money is often counted in whole cents: a computer writes those exactly. 0.1, it only gets close.
Where have you seen a number come out a tiny bit wrong?
Sources: our own run on a laptop, 2026; W. Kahan, Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic, 1997; C. Severance, An Interview with the Old Man of Floating-Point, 1998; IEEE 754-1985; US GAO, Patriot Missile Defense: Software Problem Led to System Failure at Dhahran, Saudi Arabia, GAO/IMTEC-92-26, 1992; Stripe API documentation (amounts in the smallest currency unit).
Sounds and music: made by us.
