2

This might seem really silly. But I am new to python and like to use equality conditions in my program, and has hit a very surprising road block. While the practical issue here is that the last condition r==rmax is not satisfied and I will miss out on an iteration of the loop, but that is not what is worrying me.

Rather than (trivial) work arounds, can someone explain to me what is going on in simple terms? (Also why the numbers turn out the same no matter how many times I run this loop, therefore it is something systematic and not something probabilistic). And a proper way to make sure this does not happen (What I mean by proper is a programming practice I should adopt in all my coding, so that such unintentional discrepancy does not occur ever again)? I mean such loops are omnipresent in my codes and it makes me worried.

It seems I cannot trust numbers in python, which would make it useless as a computational tool. PS : I am working on a scientific computing project with Numpy.

>>> while r<=r_max:
...     print repr(r)
...     r = r + r_step
...
2.4
2.5
2.6
2.7
2.8000000000000003
2.9000000000000004
3.0000000000000004
3.1000000000000005
3.2000000000000006
3.3000000000000007
3.400000000000001
3.500000000000001
3.600000000000001
3.700000000000001
3.800000000000001
3.9000000000000012
Rithwik
  • 1,128
  • 1
  • 9
  • 28
  • 1
    this is mainly pitfall with float arithmetic, not python in my view. – Pierre G. Nov 05 '15 at 09:45
  • Yes indeed, floating arithmetic issue. But in my younger days, when I'd program with C++, I have often used such conditions in such loops, and never have I faced such a problem. I mean to me this means, simple conditional statements in my previous (and future) python programs could be wrong and hence missing out on some important iterations. In scientific computing, you do not want to make such mistakes. – Rithwik Nov 05 '15 at 09:52
  • I think this is related to the way the floats are really implemented (in your younger days, and now, the floats may be handled a bit differently). IMHO, loops shall be written with < instead of = ; likewise comparison to zero shall be managed via a comparison like : abs(number) – Pierre G. Nov 05 '15 at 10:01
  • Yes, avoiding equality condition would be a good practice to pick up. Thanks a lot Pierre G. How do I mark your comment as helpful? – Rithwik Nov 05 '15 at 10:11

3 Answers3

1

The simple answer is that floating-point numbers, as usually represented in computing, aren't exact, and you can't treat them as if they were exact. Treat them as if they're fuzzy; see if they're within a certain range, not whether they "equal" something.

The numbers turn out the same because it's all deterministic. The calculations are being done in exactly the same way each time. This isn't a case of random errors, it's a case of the machine representing floating-point numbers in an inexact way.

Python has some exact datatypes you can use instead of inexact floats; see the decimal and fractions modules.

There's a classic article called "What Every Computer Scientist Should Know About Floating-Point Arithmetic"; google it and pick any link you like.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
0

Pierre G. is correct. Because computer calculate number in binary, it cannot present a lot float number exactly. But it should be precise with in certain digits depends the data type you use.

For your case, I think maybe you could use round(number, digits) function to get a round number and then compare it.

Xiaoqi Chu
  • 1,497
  • 11
  • 6
  • 1
    Thanks for the suggestion. But I think adding this `round(number,digits)` could make the code a lot less appealing and crowded. Maybe better ways to take care of this(?). – Rithwik Nov 05 '15 at 10:09
0

It's just the matter of float arithmetic. Actually If you know about the representation of floating numbers in the computer memory, then the representation of certain numbers though we consider to be whole integer, is not stored as a whole integer. It's stored with certain precision(in terms of number of digits after decimal point) only. This problem will remain always, whenever you are doing mathematical programming. I suggest you to use comparision, which can accept tolerance value. Numpy has such methods, which facilitates such comparision.

Mangu Singh Rajpurohit
  • 10,806
  • 4
  • 68
  • 97