-2

Today I was doing my university programming classes exercises and came up to this weird thing. I would like to know if anyone could explain to me what's going on here.

This is the thing I coded to show it:

program problema;

var 

a : real;
b : real;

begin

a := 1 - 0.8 - 0.2;
b := 1 - 0.2 - 0.8;

write(a);
writeln(b);

end.

While I expected it to return 0 in both cases, it actually returns -1.3... on the first one and 0 on the second one. How can that be possible?

rolind
  • 9
  • 3
  • 5
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – JJJ Sep 22 '16 at 08:06
  • Note that it's not -1.3... but -1.3...E-020, which is -0.000...13 (with 20 zeros). – JJJ Sep 22 '16 at 08:07
  • It evaluates to -5.55111512313e-17 in PHP, and on my Fedora desktop calculator. So it's a broad symptom of computer math, not just pascal. :) See this for reference to the exact issue: http://matlab.wikia.com/wiki/FAQ#Why_is_0.3_-_0.2_-_0.1_.28or_similar.29_not_equal_to_zero.3F – SomeDude Sep 22 '16 at 08:08
  • 2
    I don't have Pascal on my PC, but what happens when you replace 0.2 by 0.125 and 0.8 by 0.875 (in order to divide by a power of 2)? As computers are based on base-2, this problem should not occur then. – Dominique Sep 22 '16 at 08:25
  • @Dominique: No, then it doesn't occur. But I guess user3494378 expected to see `0` for all kinds of numbers, e.g. `1 - 0.3 - 0.7` too, in other words: he expected exact results.And then, this is a duplicate. – Rudy Velthuis Sep 23 '16 at 10:39
  • FWIW, to see what is going on, read [my article about floating point](http://www.rvelthuis.de/articles/articles-floats.html). It should explain this pretty well, and it easier to read than the other link. And it is focused on Delphi/Pascal. – Rudy Velthuis Sep 24 '16 at 08:59

1 Answers1

0

You are seeing round off errors when dealing with decimals expressed in binary. The other commenters have implied that but just didn't say it specifically.

To deal with this it is important to judge equality as a range rather than an equality. For example, to decide if a real number x is equal to 0.2, test it not as x=0.2, but rather for |x-0.2|< epsilon, where epsilon is the tolerance you want. Perhaps abs(x-0.2)<0.000001 is good enough.

kd4ttc
  • 1,075
  • 1
  • 10
  • 28