-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sum
float precision issue
#126181
Comments
Duplicate of #111933 |
So, in short:
Answer 0.0 is not accurate in fact, you can easily do exact calculations for given floats: >>> from fractions import Fraction as F
>>> lst = [2.5392, 0.4608, -3.0]
>>> lst_F = list(map(F.from_float, lst))
>>> sum(lst_F) # nonzero!
Fraction(1, 9007199254740992)
>>> sum(lst_F) - F.from_float(sum(lst)) # sum(lst) produces exact answer here
Fraction(0, 1) |
Yes, I understand that I shouldn't do equality comparison with floats. The problem I have is that those three numbers in my example come from another piece of my program that runs an optimization (using scipy.optimize) with the constraint that the sum of those three numbers is <= 0. But when I then check that constraint in Python, it doesn't hold. The issue with this is that |
That's a bad idea for any computed floating-point values, not just sums.
I would guess, that this constraint is about the sum of three real numbers. Floating-point numbers aren't real numbers from analysis course.
How you intuition live with the fact that (a + b) + c != a + (b + c) in general? ;) >>> (0.1 + 0.2) + 0.3
0.6000000000000001
>>> 0.1 + (0.2 + 0.3)
0.6
>>> 0.2 + (0.1 + 0.3)
0.6000000000000001 This is not a worst case. It's easy to find floating-point numbers, where all three possible sums (as commutativity holds for addition, only associativity is broken) - are different: >>> while True:
... a, b, c = [random.random() for _ in range(3)]
... ss = [(a + b) + c, a + (b + c), b + (a + c)]
... if ss[0] != ss[1] and ss[1] != ss[2] and ss[0] != ss[2]:
... print([a, b, c])
... print(ss)
... break
...
[0.457290196955373, 0.7565955400028612, 0.38914139486258204]
[1.6030271318208165, 1.603027131820816, 1.6030271318208162] |
Ok, point taken. I need to revise my intuitions. ;) |
On the plus side (pun intended), your intuitions about commutatively are now likely to be correct.
Formerly, this would have returned something like |
And ~60% already for four arguments. |
Bug report
Bug description:
I am encountering some strange results in Python 3.12.3 when summing up numbers using the
sum
function.It seems that there are some precision issues, which I wouldn't expect with these numbers:
I tested on the official docker images of Python 3.11 - 3.13 and version 3.13 also seem affected (3.11 works as expected).
CPython versions tested on:
3.12, 3.13
Operating systems tested on:
Linux, macOS
The text was updated successfully, but these errors were encountered: