0

I have this list of numbers

num = [3.700872591587623, 3.083141235300246, 3.700872591587623, 2.321928094887362, -0.0, 5.088040034713085, 3.8079321155203494, 3.0, 3.8079321155203494, 3.700872591587623, -0.0, -0.0, 5.088040034713085, 5.088040034713085, 3.8079321155203494, 3.8079321155203494]

And I have these three smaller partitions of the above list

list_1 = nums[:5]   # Elements 0 to 4
list_2 = nums[5:-1] # Elements 5 to len(list) - 1
list_3 = nums[-1:]  # Element len(list) - 1

Equivalence test:

>>> nums == list_1 + list_2 + list_3
True

When I sum the bigger list, I get the following value

>>> sum(nums)
50.003535671171136

But when I sum the smaller lists, and add them together, I get a different value (logically they should give you the same value)

>>> sum(list_1) + sum(list_2) + sum(list_3)
50.00353567117113

Specifically, sum(nums) gives a value that is 0.00000000000006 larger. This minor difference fails an equivalence test, which makes a difference in the decision making in my program. I'd like those two operations to be executed "reliably". Is there a way to ensure that?

Naldhelaan
  • 390
  • 4
  • 13
  • 2
    You shouldn't test floats for equality, due to the limitations of representing infinite real numbers in finite memory they are an approximation only. Do something like `abs(f1 - f2) < 0.000001` to ensure they're close within a tolerance. – jonrsharpe Oct 30 '16 at 14:18
  • 1
    You could also use `math.isclose`: `math.isclose(50.003535671171136, 50.00353567117113) -> True` – vaultah Oct 30 '16 at 14:19
  • Is it safe to multiply all of the floats by a scalar value (say, 100,000) and check the equivalence similarly? It works for this particular case, but I'm not sure if its safe across all cases. – Naldhelaan Oct 30 '16 at 14:26
  • How do you define *"safe"*? What level of precision is appropriate for your task? Perhaps you should consider `decimal`s? – jonrsharpe Oct 30 '16 at 14:28
  • @Naldhelaan It **cannot** work in all cases. That's just how `float`s are designed: they are inherently imprecise. Operations on float numbers are *not* associative, so it is **not** true that `x + (y + z) == (x + y) +z`! Even though according to maths that should be true. – Bakuriu Oct 30 '16 at 14:29
  • I don't foresee comparisons on values less than 1 * 10^-6. My program rarely reaches that level of precision. This particular question is just a corner case where the values got really close to each other. – Naldhelaan Oct 30 '16 at 14:35
  • @Bakuriu thanks for the comment. `Decimal` is probably the better choice then. – Naldhelaan Oct 30 '16 at 14:37

0 Answers0