Message195646
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. |
|
Date |
User |
Action |
Args |
2013-08-19 16:35:54 | steven.daprano | set | recipients:
+ steven.daprano, terry.reedy, gregory.p.smith, ronaldoussoren, mark.dickinson, belopolsky, pitrou, agthorr, christian.heimes, stutzbach, sjt, ethan.furman, tshepang, oscarbenjamin, vajrasky |
2013-08-19 16:35:54 | steven.daprano | link | issue18606 messages |
2013-08-19 16:35:53 | steven.daprano | create | |
|