FAQ: Why is 0.3 - 0.2 - 0.1 not equal to zero?

Asked by Jan Simon

Jan Simon (view profile)

on 26 Dec 2012

Why does

`   0.3 - 0.2 - 0.1 == 0`

or

```   v = 0:0.1:1;
any(v == 0.3)```

(or similar numbers) reply false?

Jan Simon

Jan Simon (view profile)

on 26 Dec 2012

This is an experimental question only! There is no need to answer it and please do not vote for it. This is neither my question nor my answer, but only an example for a nicer, more convenient, more usable FAQ, which is less stuffed with commercials.

Products

No products are associated with this question.

Jan Simon (view profile)

Answer by Jan Simon

Jan Simon (view profile)

on 26 Dec 2012
Edited by Jan Simon

Jan Simon (view profile)

on 26 Dec 2012

0.3 - 0-2 - 0.1 returns -2.7756e-17.

As is mentioned frequently in the newsgroup, some floating point numbers can not be represented exactly in binary form. So that's why you see the very small but not zero result. See EPS.

The difference is that 0:0.1:0.4 increments by a number very close to but not exactly 0.1 for the reasons mentioned below. So after a few steps it will be off whereas [0 0.1 0.2 0.3 0.4] is forcing the the numbers to their proper value, as accurately as they can be represented anyway.

```   a  = [0 0.1 0.2 0.3 0.4];
b  = 0:.1:.4;
as = sprintf('%20.18f\n',a)```
```>> as =
0.000000000000000000 % ==
0.100000000000000010 % ==
0.200000000000000010 % ==
0.299999999999999990 % ~= bs !
0.400000000000000020 % ==
```
`   bs = sprintf('%20.18f\n',b)`
```>> bs =
0.000000000000000000 % ==
0.100000000000000010 % ==
0.200000000000000010 % ==
0.300000000000000040 % ~= as !
0.400000000000000020 % ==
```

and:

```   format hex;
hd = [a.',b.']```
```>> hd =
0000000000000000   0000000000000000 % ==
3fb999999999999a   3fb999999999999a % ==
3fc999999999999a   3fc999999999999a % ==
3fd3333333333333   3fd3333333333334 % ~= !
3fd999999999999a   3fd999999999999a % ==
```

If you're trying to compare two floating-point numbers, be very careful about using == to do so. An alternate comparison method is to check if the two numbers you're comparing are "close enough" (as expressed by a tolerance) to one another:

```% instead of a == b
% use:
areEssentiallyEqual = abs(a-b) < tol
% for some small value of tol relative to a and b
% perhaps defined using eps(a) and/or eps(b)
```

You can see this same sort of behavior outside MATLAB. Using pencil and paper (or a chalkboard, or a whiteboard, etc.) compute x = 1/3 to as many decimal places as you want. The number of decimal places must be finite, however. Now compute y = 3*x. In exact arithmetic, y would be exactly 1; however, since x is not exactly one third but is a rounded approximation to one third, y will not be exactly 1.

For a readable introduction to floating point arithmetic, look at Cleve's Corner article from 1996: Floating Points (PDF) http://www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf

For more rigorous and detailed information on floating point arithmetic, read the following paper: What Every Computer Scientist Should Know About Floating Point Arithmetic http://docs.sun.com/source/806-3568/ncg_goldberg.html

Another resource is Technical Note 1108 http://www.mathworks.com/support/tech-notes/1100/1108.html on the Support section of The MathWorks website.

This answer is copied and slightly modifed from matlab.wikia.com/wiki/FAQ: Why_is_0.3-0.2-0.1_not_equal_to_zero

Join the 15-year community celebration.

Play games and win prizes!

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi