[Tutor] decimal module and precision

Richard D. Moores rdmoores at gmail.com
Mon Jan 31 16:23:11 CET 2011


On Mon, Jan 31, 2011 at 05:24, Eike Welk <eike.welk at gmx.net> wrote:
> Hello Richard!
>
> In your code:
>
>   d(123.2345274523452345235432452345)
>
> you are entering the number as a `float` and you are loosing the precision
> already when the code is compiled. To retain the precision all constants must
> be entered as strings.
>
> For illustration see this part of an interactive Python session:
>
>>>> 123.123456789012345678901
> 123.12345678901235
>
> The other issue with floating point is, that only very few numbers can be
> accurately represented. These numbers must be composed from (including
> negative) powers of two. Like this: 0.5 + 0.25 + 0.125 + 0.0625 ...
> Numbers that cant be represented accurately:
>
>>>> 0.1
> 0.10000000000000001
>>>> 0.3
> 0.29999999999999999

So I'll try:
>>> import decimal
>>> from decimal import Decimal as D
>>> decimal.getcontext().prec = 32
>>> print(D('23.45')**D('.34'))
2.9231329473018093516404474158812
>>> def d(x):
    return decimal.Decimal.from_float(x)
>>> print(d(23.45)**d(.34))
2.9231329473018095467750783681372

Which is accurate to only 16 digits; my Windows Vista calculator gives
2.9231329473018093516404474158812 for 23.45**.34

And using mpmath with Python 2.6 does exactly as poorly:
>>> from mpmath import mp, mpf
>>> mp.dps=32;mp.pretty=True
>>> mpf(23.45)**mpf(.34)
2.9231329473018095467750783681372

So it seems I shouldn't use d(), or my revised d(), or mpmath for
maximum precision, which seems to be at least 32 when using the
decimal module the standard way.

> It would probably be a good idea, if the Python compiler would issue a warning
> when it encounters a `float` constant with excessive precision.

Well, it sure would have helped me!

Thanks, Eike.

Dick


More information about the Tutor mailing list