Weird result returned from adding floats depending on order I add them

John Machin sjmachin at lexicon.net
Tue Feb 20 08:08:30 EST 2007


On Feb 20, 11:29 pm, "joanne matthews (RRes-Roth)"
<joanne.matth... at bbsrc.ac.uk> wrote:
> I'm getting different results when I add up a list of floats depending
> on the order that I list the floats.

This is quite expected. Floating point arithmetic is subject to
rounding errors.

[doesn't add to 1.0]
>         inputs=[0.2,0.2,0.2,0.1,0.2,0,0.1]
>
> However, if I swap, the 4th and 5th list items like this:
>
> inputs=[0.2,0.2,0.2,0.2,0.1,0,0.1]
[adds to 1.0]

What is happening:

print repr(whatever_you_are_puzzled_by) is a Very Good Idea (TM).

>>> a = [0.2, 0.2, 0.2, 0.1, 0.2, 0.1]
>>> b = [0.2, 0.2, 0.2, 0.2, 0.1, 0.1]
>>> sum(a)
1.0000000000000002
>>> sum(b)
1.0
>>> tot = 0.0
>>> for x in a:
...    tot += x
...    print repr(x), repr(tot)
...
0.20000000000000001 0.20000000000000001
0.20000000000000001 0.40000000000000002
0.20000000000000001 0.60000000000000009
0.10000000000000001 0.70000000000000007
0.20000000000000001 0.90000000000000013
0.10000000000000001 1.0000000000000002
>>> tot = 0.0
>>> for x in b:
...    tot += x
...    print repr(x), repr(tot)
...
0.20000000000000001 0.20000000000000001
0.20000000000000001 0.40000000000000002
0.20000000000000001 0.60000000000000009
0.20000000000000001 0.80000000000000004
0.10000000000000001 0.90000000000000002
0.10000000000000001 1.0
>>>

As you can see, 0.1 and 0.2 can't be represented exactly as floating
point numbers. Consequently there is only a rough chance that they
will add up to what you think they should add up to.

Fixes:

(1) Round the sums to a suitable precision.
>>> round(sum(a), 3)
1.0
>>> round(sum(b), 3)
1.0
>>>

(2) Test against a range, rather than for equality:

>>> abs(sum(a) - 1.0) < 0.001
True
>>> abs(sum(b) - 1.0) < 0.001
True
>>>

(3) Use the Decimal module

(4) Google this group (or the Python cookbok, I forget which) for
fancy algorithms for doing accurate sums of lists of floats.

HTH,
John




More information about the Python-list mailing list