Why not FP for Money?

Chris Barker Barkmann at gmail.com
Thu Sep 23 07:03:43 CEST 2004


"Batista, Facundo" <FBatista at uniFON.com.ar> wrote in message 
> Well, actually that's an issue, because the "banker's rounding" is not the
> same rounding in every country.
> 
> That's why in Decimal you have a lot of roundings to choose.

Exactly. I am the OP, and my question was "What am I missing?", and
that is the above is the answer.

I had started with the assumption that the IEEE 754 rounding methods
were about as good as anyone was likely to get, and certainly better
than I was going to come up with on my own. What I had missed was that
accounting has rules about rounding, and your accounting package had
better follow the appropriate rules. Once you are handling all the
rounding yourself, you might as well use integers.

To address a few other points, just so I don't look like an idiot for
all posterity in usenet.

I'm well aware of the difference between base ten and two. That really
isn't the issue here. binary FP can represent fractions jsut as
accurately as decimal, it's just a different set that they represent.
Perhps accounting rules have base ten built into them, but other than
that, the only advantage is familiarity: people expect 1/10 to be
represented exactly, but don't expect 1/3 to be. As far as money is
concerned, there is no real advantage, other than convention, to
perfectly representing 1/10 of a cent, but not 1/3 of a cent. With
binary FP, you can't represent 1/10 of a cent exactly, but you can get
darn close, and if you round the answer to pennies when your done, it
will be just as accurate as decimal (given how many bit you use,
etc.), in general.

Now to address a few specific points made (sorry to lose the
attribution):
"""
Floating point arithmetic is useful for continuous quantities,
or quantities that are measured (as in weighed, etc.) Integers
(and rationals) are useful for things that are counted, which
includes currency units, but also includes anything else that
comes in discrete units  (apples and oranges, for instance).
"""

That only applies until you start slicing the oranges, and only
applies here if you are dealing with actual pennies. When people
calculate interest, tax, etc, they want to deal in fractional pennies.
That's why we can't just use integer pennies and have done with it.
However, it is true that while fractions do need to be dealt with, the
should not "float". That being said, as someone mentioned, accounting
practices are not neccsarily logical. Personally, thinking of money it
terms of significant digits would be fine with me. Is there really any
point in keeping track of the pennies when talkin gof trillions of
dollars?

"""
Beware! Floating point errors may bite you *even for non-fractional
numbers*
"""

I tried to address that in the OP. 64 bit IEEE FP carries a lot of
digits! This isn't an issue till you get to quadrillions of dollars.
The same issue comes up if you use standard integers, though then you
will get overflow instead. If not handled right, that could REALLY
give strange results! Fortunatly Python now automatically rolls over
to long integers.

"""
But you'll get different answers than decimal arithmetic would give
you, so the auditors will be all over your ass if you do it that way.
You don't want that.  You need decimal arithmetic.
"""

right. that is a matter of convention, not precision.

Tim, thanks for the references. I had seen that paper by Kahan, but
had forgotten it. However, it doesn't address my question, the main
point here is that "Decimal displays of Binary nonintegers cannot
always be WYSIWYG" This is entirely a perceptual problem, not an
accuracy one, though I suppse when it comes to money...perception is
very important!

The IBM references were informative as well.

One interesting distiction here: binary vs. decimal and floating point
vs. fixed point are orthoganal concepts that have been mingled here.
Alex pointed out that decimal floating point has the same problems as
binary as far as accuracy is concerned.

"""
What we'd _really_ want to specify is 'keep exactly two digits AFTER
the
decimal point, no matter how many there are BEFORE', but that's not
decimal's job -- it's still a floating point type, albeit decimal, NOT
a
fixed-point one.  Maybe we do need a fixed-point-decimal for 2.5...?
"""

Or a currency type, specifically. 

"""
consider, for 
example, a program that calculates payments on a real estate mortgage.
Given that interest may need to be calculated on a daily basis, and
that
the daily interest rate is a very small fraction, the imprecision of 
floating point can then become much more significant relative to the 
desired quantity.  And given that there's a *lot* of calculations over
which this imprecision can build (a 30-year mortgage ~= 10957 days),
and
the exponential nature of the interest calculation, this can become a 
real issue.
"""

OK, so how the heck do you do that? Any system, fixed or FP, binary or
decimal, is going to have the same issue. I think the answer is that
you have to round, but you can follow the appropriate accounting
practice when you do so.

thanks everyone, for some enlightening discussion.

-Chris



More information about the Python-list mailing list