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 <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