0

I noted a strange thing summing up numbers in a list:

>>> mylist = [200.2345, 300.5, 6000000.0]
>>> sum(mylist)
6000500.7345 ==> OK
>>> mylist = [200.2345, 300.5, 200.2345]
>>> sum(mylist)
700.969 ==> OK
>>> mylist = [200.2345, 6000000.0, 200.2345]
>>> sum(mylist)  
6000400.4690000005 ==> WRONG

What's happening here?
Did I do something wrong or is it a bug in sum()?

Reman
  • 7,931
  • 11
  • 55
  • 97
  • 3
    Well float point number happened – styvane Apr 12 '16 at 20:57
  • 1
    This is a float problem versus a sum problem. Basically, how the data is stored in python when it comes to decimals – Adib Apr 12 '16 at 20:57
  • 1
    From python documentation: "The exactness carries over into arithmetic. In decimal floating point, 0.1 + 0.1 + 0.1 - 0.3 is exactly equal to zero. In binary floating point, the result is 5.5511151231257827e-017. While near to zero, the differences prevent reliable equality testing and differences can accumulate. For this reason, decimal is preferred in accounting applications which have strict equality invariants." Source: https://docs.python.org/2/library/decimal.html – Adib Apr 12 '16 at 21:00
  • @Adib, how can I have the correct result? Sorry that my question in a duplicate. I will delate it. – Reman Apr 12 '16 at 21:04
  • @Reman One solution I can think of is using `round()` to round up to closest possible figure. Another good solution is dividing the two numbers and seeing how close they are to the int. – Adib Apr 12 '16 at 21:06
  • @Adib dividing the two numbers and seeing how close they are to the int? – Reman Apr 12 '16 at 21:07
  • For your case, you can try this: `>>>mylist = [200.2345, 6000000.0, 200.2345] >>> int_sum = int(sum(mylist)) >>> ratio = round(int_sum/sum(mylist),2) >>> if ratio == 1.00: #Do something` – Adib Apr 12 '16 at 21:12
  • @Adib, in 2nd example (the correct output) the ration = `0.9986176278836867` and the 3rd example (the wrong output) the ratio is `0.9999999218385501` Still don't understand what I have to do and what is the difference between both – Reman Apr 12 '16 at 21:18
  • @Reman My point is that you should round to the number of significant figures you care about (for example, the accuracy should be at least 3 decimal points). Then you compare based on that rounding. – Adib Apr 12 '16 at 21:25
  • @Adib, Would this be ok? `float(decimal.Decimal("200.2345") + decimal.Decimal("300.5") + decimal.Decimal("200.2345"))` – Reman Apr 12 '16 at 21:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/108980/discussion-between-adib-and-reman). – Adib Apr 12 '16 at 21:33

0 Answers0