[Python-Dev] sum()

Raymond Hettinger python at rcn.com
Sat Mar 12 13:17:36 CET 2005

> [Tim Peters]
> Summer.add() _can_ lose info -- it needs additional
> trickery to make it loss-free, and because x+y can lose (at most one
> bit) when x and y have the same binary exponent.

Computing an error term can get the bit back and putting that term back
in the input queue restores the overall sum.  Once the inputs are
exhausted, the components of exp2sum should be exact.

from math import frexp
from itertools import chain

def summer2(iterable):
    exp2sum = {}    
    queue = []
    for x in chain(iterable, queue):
        mant, exp = frexp(x)        
        while exp in exp2sum:
            y = exp2sum.pop(exp)
            z = x + y
            d = x - z + y   # error term
            assert z + d == x + y
            if d:
            x = z
            mant, exp = frexp(x)
        exp2sum[exp] = x
    return sum(sorted(exp2sum.itervalues(), key=abs), 0.0)

The implementation can be tweaked to consume the error term right away
so the queue won't grow by more than few pending items.  Also, the speed
can be boosted by localizing frexp, exp2sum.pop, and queue.append.

Raymond Hettinger

More information about the Python-Dev mailing list