Oscar Benjamin added the comment:

On 12 August 2013 20:20, Steven D'Aprano <rep...@bugs.python.org> wrote:
> On 12/08/13 19:21, Mark Dickinson wrote:
>> About the implementation of sum:
> add_partial is no longer documented as a public function, so I'm open to 
> switching algorithms in the future.

Along similar lines it might be good to remove the doc-test for using
decimal.ROUND_DOWN. I can't see any good reason for anyone to want
that behaviour when e.g. computing the mean() whereas I can see
reasons for wanting to reduce rounding error for decimal in
statistics.sum. It might be a good idea not to tie yourself to the
guarantee implied by that test.

I tried an alternative implementation of sum() that can also reduce
rounding error with decimals but it failed that test (by making the
result more accurate). Here's the sum() I wrote:

def sum(data, start=0):

    if not isinstance(start, numbers.Number):
        raise TypeError('sum only accepts numbers')

    inexact_types = (float, complex, decimal.Decimal)
    def isexact(num):
        return not isinstance(num, inexact_types)

    if isexact(start):
        exact_total, inexact_total = start, 0
    else:
        exact_total, inexact_total = 0, start

    carrybits = 0

    for x in data:
        if isexact(x):
            exact_total = exact_total + x
        else:
            new_inexact_total = inexact_total + (x + carrybits)
            carrybits = -(((new_inexact_total - inexact_total) - x) - carrybits)
            inexact_total = new_inexact_total

    return (exact_total + inexact_total) + carrybits

It is more accurate for e.g. the following:
    nums = [decimal.Decimal(10 ** n) for n in range(50)]
    nums += [-n for n in reversed(nums)]
    assert sum(nums) == 0

However there will also be other situations where it is less accurate such as
    print(sum([-1e30, +1e60, 1, 3, -1e60, 1e30]))
so it may not be suitable as-is.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue18606>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to