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:
- https://0.30000000000000004.com/
- qntm's explanation of why 0.1 + 0.2 is not 0.3 in computers
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- Concise-r explanation as well as a general floating-point guide.
- Floating-point arithmetic on Wikipedia.
- The actual standard (why does this cost $110?).
- This stackoverflow question has many answers and comments providing details from some other perspectives as well.
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)
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:
When using double precision floating point numbers (the IEEE 754 standard).