Precise calculations

Bengt Richter bokr at oz.net
Sat Nov 8 19:10:23 EST 2003


On Fri, 07 Nov 2003 13:17:44 GMT, "Ladvánszky Károly" <aa at bb.cc> wrote:

>Could anybody help me on how to do precise calculations with Python the way
>hand-held calculators do?
>
>A small example to show the impreciseness coming from the floating point
>arithmetics:
>
>(100000000000000.4*3)*100 gives 30000000000000124.0
>

By coincidence I just posted a module (very alpha code, see "prePEP: Decimal data type" thread)
that does exact decimal floating point, so you can do better than hand calculators ;-)

First, let's use it to show what the full floating point bits ('all') show when converted
to an exact representation:

 >>> from exactdec import ED
 >>> ED(100000000000000.4,'all')
 ED('100000000000000.40625')
 ^
 +--the _actual_ floating point value represented

 >>> ED(100000000000000.4,'all')*3
 ED('300000000000001.21875')
 ^
 +-- an exact multiple by 3

 >>> ED(100000000000000.4*3,'all')
 ED('300000000000001.25')
 ^
 +--the exact value of the inexact floating point product

 >>> ED(100000000000000.4*3,'all')*100
 ED('30000000000000125')
 ^
 +--times 100 exactly

 >>> ED(100000000000000.4*3*100,'all')
 ED('30000000000000124')
 ^
 +--the result of the additional floating point multiply

Now doing the math starting with an exact string literal for your starting value:

 >>> ED('100000000000000.4')
 ED('100000000000000.4')
 ^
 +--value is exact

 >>> ED('100000000000000.4')*3
 ED('300000000000001.2')
 ^
 +--product is exact (the right operand of 3 is converted like ED(3) which is exact
    since integer is exact.

 >>> (ED('100000000000000.4')*3)*100
 ED('30000000000000120')
 ^
 +--similarly with the  100 factor, which is converted to exact before multiplying as well.

Now try this on your calculator (note the binomial thing):

 >>> b = ED('1001001001001001001001001001')
 >>> b
 ED('1.001001001001001001001001001e27')
 >>> b*b
 ED('1.002003004005006007008009010009008007006005004003002001e54')
 >>> b*b*b
 ED('1.003006010015021028036045055063069073075075073069063055045036028021015010006003001e81')

;-)

Regards,
Bengt Richter




More information about the Python-list mailing list