-2

I have two variables:

result = 121.0 #  initialized in code, assigned in loop
dd = -121.0 #  value returned from result of function

So, when I do

result += dd 

result becomes 2.84217094304e-14 (name of this representation of numbers and algorithm of reading is welcome)

But when I assign same values in python console - it returns proper result - 0.0

What is the problem?

Vassily
  • 5,263
  • 4
  • 33
  • 63
  • Unclosed as dupe because the example has no floating point inaccuracy. A correct dupe would mention Python 2's misleading floating point printing instead, although "cannot reproduce" is fair too. I'll look for a dupe now. – Veedrac Jan 12 '16 at 07:34
  • As mentioned above, this doesn't reproduce your claim. `a + (-a)` will always cancel exactly for finite non-NaN floats. – Veedrac Jan 12 '16 at 07:35
  • I can't find a proper dupe. I'll give this an answer instead, but I *know* I've seen this around before a few times. – Veedrac Jan 12 '16 at 07:40
  • 1
    As far as I can see this is simply because dd is calculated value, it is around -121 - 2e-14, rounded to 121.0 for print. Although cannot reproduce is correct without knowing how dd is calculated. – Koebmand STO Jan 12 '16 at 07:40

2 Answers2

0

Your numbers might appear to be 121.0 and -121.0, but that is the fault of inaccuracies in printing. I believe this occurs with repr in earlier Python versions (which print uses), although you might be explicitly rounding their representation elsewhere.

When you add them together, the inaccuracy ceases to be rounded off and the difference is visible. If you actually had the values you claim, you would get exactly 0.0.

Note that in general you cannot get perfectly accurate results from floating point calculations, although you may in some circumstances. If these are calculated with error, you'll need to take that into account manually.

Veedrac
  • 58,273
  • 15
  • 112
  • 169
  • Yep. Round helps. Thanks for explanation ;) As I understand from comments - it's only python 2 problem? Do you recommend to use python3? – Vassily Jan 12 '16 at 07:47
  • @VassiliyVorobyov You should be *very* careful using `round`. For example, `round(a) == round(b)` can give false even if `a` and `b` are only the smallest possible difference apart, as long as they lie in the right place. Further, if you're using `round` for display purposes, you should also be careful - there's little guarantee that the number produced will actually be represented to that number of decimal places (because floats aren't a decimal system). `round` *might* be the right choice - I don't know what you're doing with it after all - but it rarely is. – Veedrac Jan 12 '16 at 07:50
0

It's perfectly ok for floating point numbers. It's because of how floating point numbers are implemented in hardware and it's mostly has nothing to do with Python itself. In later versions of Python 2.7 and Python 3.1+ the display logic is improved and usually prints in a more conscious way, though in machine memory the numbers are still kept in the same way.

That's why you don't want to use floating point for money representation and use decimal instead. ;)

Learn more at:

http://floating-point-gui.de/

http://docs.python.org/2/tutorial/floatingpoint.html

And if you really care and have time there's a big article at Oracle docs.

Nikita
  • 6,101
  • 2
  • 26
  • 44