Steven D'Aprano added the comment:
On 19/08/13 23:15, Oscar Benjamin wrote:
> So with the current implementation I can do:
>
>>>> from decimal import Decimal as D, localcontext, Context, ROUND_DOWN
>>>> data = [D("0.1375"), D("0.2108"), D("0.3061"), D("0.0419")]
>>>> print(statistics.variance(data))
> 0.01252909583333333333333333333
>>>> with localcontext() as ctx:
> ... ctx.prec = 2
> ... ctx.rounding = ROUND_DOWN
> ... print(statistics.variance(data))
> ...
> 0.010
>
> The final result is not accurate to 2 d.p. rounded down. This is
> because the decimal context has affected all intermediate computations
> not just the final result.
Yes. But that's the whole point of setting the context to always round down. If
summation didn't always round down, it would be a bug.
If you set the precision to a higher value, you can avoid the need for
compensated summation. I'm not prepared to pick and choose which contexts I'll
honour. If I honour those with a high precision, I'll honour those with a low
precision too. I'm not going to check the context, and if it is "too low"
(according to whom?) set it higher.
>Why would anyone prefer this behaviour over
> an implementation that could compensate for rounding errors and return
> a more accurate result?
Because that's what the Decimal standard requires (as I understand it), and
besides you might be trying to match calculations on some machine with a lower
precision, or different rounding modes. Say, a pocket calculator, or a Cray, or
something. Or demonstrating why rounding matters.
Perhaps it will cause less confusion if I add an example to show a use for
higher precision as well.
> If statistics.sum and statistics.add_partial are modified in such a
> way that they use the same compensated algorithm for Decimals as they
> would for floats then you can have the following:
>
>>>> statistics.sum([D('-1e50'), D('1'), D('1e50')])
> Decimal('1')
statistics.sum can already do that:
py> with localcontext() as ctx:
... ctx.prec = 50
... x = statistics.sum([D('-1e50'), D('1'), D('1e50')])
...
py> x
Decimal('1')
I think the current behaviour is the right thing to do, but I appreciate the
points you raise. I'd love to hear from someone who understands the Decimal
module better than I do and can confirm that the current behaviour is in the
spirit of the Decimal module.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue18606>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com