[Tutor] decimal module and precision
Richard D. Moores
rdmoores at gmail.com
Mon Jan 31 13:25:35 CET 2011
On Mon, Jan 31, 2011 at 01:32, Steven D'Aprano <steve at pearwood.info> wrote:
> Richard D. Moores wrote:
>>
>> Python 3.1
>> The decimal module continues to puzzle me from time to time. Here's
>> one of those. I want to use Alex Martelli's factory function as much
>> as possible. Turns out it has a problem with precision in addition and
>> multiplication.
>>
>> =========================================
>> from decimal import Decimal as D
>> import decimal
>>
>> #Alex Martelli's factory function from 'Python in a Nutshell', 2nd ed.,
>> p.373
>> def d(x):
>> return decimal.Decimal(str(x))
>
>
> I don't have the second edition of the book, only the first. Are you sure
> that Alex Martelli calls this a *factory* function? It doesn't look like a
> factory to me.
Quoting from p. 373, just before the function d():
"... you can easily write a factory function for ease of
experimentation, with decimal:"
(But I should confess that I have only a very foggy idea what a
factory function is.)
>> decimal.getcontext().prec = 55
>>
>> print('power')
>> a = D('123.2345274523452345235432452345')**D('2.3')
>> a2 = d(123.2345274523452345235432452345)**d(2.3)
>> print('a =', a)
>> print('a2 =', a2)
>> print()
>
> And here is your problem:
>
>>>> str(123.2345274523452345235432452345)
> '123.234527452'
>
> Consequently:
>
>>>> D(str(123.2345274523452345235432452345))
> Decimal('123.234527452')
>
>
>> Why in the world does precision not work for addition and
>> multiplication (see x2 and z2)?
>
> It does. You are misinterpreting the error. The problem is not with the
> addition, but with the construction *before* the addition.
But the same construction, d(), is used for power and division, and
the precision of the outputs is correct. Or have I misunderstood you?
For your reference, here's the script (with output) I originally
posted about:
<http://tutoree7.pastebin.com/Chcb80HC>
> By the way, if you are using Python 2.7 or 3.1, you should consider using
> the Decimal.from_float method.
Ah, that solves my problem. See
<http://tutoree7.pastebin.com/Rt4xhtA2>. Thanks!
the precision is correct for all 4 cases. Not only that, but
a, x, y, z equal a2, x2, y2, z2 , respectively.
But a new (minor) question has arisen with Decimal.from_float. How
could I abbreviate that to, say, D, when I don't want to use d()?
>>> from decimal import Decimal.from_float as D
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
Syntax Error: from decimal import Decimal.from_float as D: <string>, line 128
Write a function, I suppose?
import decimal
def D(x):
return decimal.Decimal.from_float(x)
decimal.getcontext().prec = 80
x = 34.56
y = 54
a = D(x)**D(y)
print(a)
"""
OUTPUT
1.2105469158150833527405908484753780279256714499986841719510192301537218650731014E+83
"""
Dick
More information about the Tutor
mailing list