Why not FP for Money?

Alex Martelli aleaxit at yahoo.com
Wed Sep 22 12:35:44 EDT 2004


Christos TZOTZIOY Georgiou <tzot at sil-tec.gr> wrote:
   ...
>         amount= tp(repr(amount))
>         vat= amount * tp('0.18')
>         total= amount + vat
   ...
> import decimal
> quote(decimal.Decimal)
> quote(float)
> 
> Run it with Python 2.4.  See what goes wrong?  Put the numbers in an
> Excel sheet too.

The problem is pretty clear, but it shows up with decimal just as well
as with float: each of 'amount' and 'vat' (in Euro) has a fraction of a
eurocent that is less than 0.5 (about 0.4 eurocents each), and you don't
round them to eurocents before summing, so the total ends up with a
fraction of a eurocent that is _more_ than 0.5.  So the final numbers
show, identically badly with both decimals and floats:

Amount: USD    2025.00 EUR    1710.30
Vat   : USD     364.50 EUR     307.85
Total : USD    2389.50 EUR    2018.16

where the 1-eurocent discrepancy between 'Total' and the easily
eyeballed 'Amount'+'Vat' shows up quite nastily.  (A case of "2+2 DOES
equal 5, for sufficiently large values of 2", to quote Anna [presumably
quoting somebody else...]).


> Of course, one can take extra precautions to always have correct numbers
> when working with floats and monetary amounts (eg. I did that for the
> Excel sheet the sales dpt used).  Why bother, though, if one has the
> Decimal type?

It seems to me that you just showed that decimal is no panacea: you
still have to know where to round and to which precision.  decimal is a
great tool but is not and cannot be a magic wand...


Alex



More information about the Python-list mailing list