0.1+0.2=0.30000000000000004…

1. "Broken" (floating point) math

In computers1, the following is true: \[0.1 + 0.2 = 0.3000000000000000\mathbf{\color{green} 444089209850062616169452667236328125}\]

Short reason: Computers store numbers in binary and real numbers are stored using the IEEE 754 standard which interprets some number of bits (64-bits in this case) as a real number. Of course, a fixed number of bits cannot really represent the infinite precision of real numbers. This means that some details are lost in translation floating-point and we get "broken" math.

Please read these better explanations:

2. Code

2.1. Python

Try out the following in the python interpreter

print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3) # Outputs false

In python all non-integers are double-precision (64-bit) IEEE 754 standard floating-point numbers.

2.2. Haskell

Try out the following in ghci

0.1+0.2 :: Double
(0.1+0.2 :: Double) == (0.3 :: Double) -- |  False

In Haskell, asking for Double all non-integers are double-precision (64-bit) IEEE 754 standard floating-point numbers. In contrast, Float in Haskell is not the same thing. Rational matches the mathematical terminology of a numerator divided by a denominator.

0.1+0.2 :: Float -- | Will be equal to 0.3
(0.1+0.2 :: Float) == (0.3 :: Float) -- | Will be True
0.1+0.2 :: Rational -- | Will be equal to 3 / 10

2.3. Elisp

In Emacs typing (+ 0.1 0.2) anywhere and then using C-x C-e immediately after the closing parenthesis will show the result.

(+ 0.1 0.2)

2.4. Javascript

Try this out in console. On Firefox, one could get there by first pressing F12 to get developer tools, going to the console tab and just typing the following in.

0.1+0.2
0.1+0.2 == 0.3

In a standalone .js file, you probably want:

console.log(0.1+0.2)
console.log(0.1+0.2 == 0.3) //Outputs false

2.5. C/C++

Compile the following code with gcc and execute the compiled binary. Since C++ is a strict superset of C, this counts as a C++ example as well.

#include <stdio.h>

int main(){
  double a = 0.1;
  double b = 0.2;
  printf("%.17f", a+b);
}

2.6. Other languages

A comprehensive list can be found at https://0.30000000000000004.com/

3. Obligatory xkcd (or math weirdness which isn't a floating point issue)

xkcd comic 217

Figure 1: xkcd comic about \(e^\pi - \pi\).

\[e^{\pi} - \pi = \mathbf{19.999}{\small 099979189}\dots \approx 20\]

\[\sqrt[4]{9^2 - \frac{19^2}{22} } \approx \mathbf{3.14159265}{\small 25826463} \approx \pi\]

See also: Almost integer on Wikipedia

Footnotes:

1

When using double precision floating point numbers (the IEEE 754 standard).

Date: May 12, 2024

Author: Akshar Varma

Created: 2024-05-12 Sun 15:13

Validate