Post by Stefan Monnier Post by Kaz Kylheku
But suppose you're dealing with currency. Then you have to round every
calculation that is supposed to produce a monetary amount (e.g. dollars
and cents). For instance if some tax calculation produces $123.45678,
you need to make that into $123.46 before entering it into the ledger.
But, AFAIU, you don't want to represent this 123.46 using a floating
point number, because your implementation's choice of floating point
numbers is probably unable to represent 123.46 exactly.
But that ("don't use floating for currency") is actually just a popular myth;
it can be done.
123.46 is not represented exactly, indeed. But, the difference between
the approximation and 123.46 is vanishingly small. It's like in the
ninth place after the decimal point or something like that.
If you round all the calculations consistently, you will always end up
with a good approximation that is far closer to the correct penny
than to any other penny.
The problem with floating-point is mainly range: if you're
astronomically rich, then you no longer /have/ an approximation for each
penny that is closer to it than to any other penny.
IEEE 64 bit yields 15 digits of precision. A decimal number confined to
15 digits can be converted to a 64 bit double and back without loss of
digits (if it is in range of the type).
15 digits is a lot of dollar, even if we use two of those digits for cents.
You have to be astronomically rich before you have a range-induced
Post by Stefan Monnier
IOW when dealing with such numbers you'll want to use "fixed point"
numbers or fractional numbers so you can have precise control over
The only situation in which you would want precise rounding control
would be when a specific pencil-and-paper rule is dictated: how you
should round a fractional result to the smallest monetary unit
(such as penny).
That's not related to dealing with rounding error: when we fix $0.12345
to $0.12, we are not fixing an error; we are *introducing* one, a rather
large one, for the sake of pragmatics.
If you have to conform with specific rules about rounding, those will be
based on a decimal representation. You can implement them by printing a
decimal representation of the number into a string, and dealing with the
For instance, we take 0.123456 and first print it, such that it is
clamped to four digits (using the printing routine's own rounding
method): "0.1235". Now we have a character string, in which a four-digit
fractional part is in a fixed trailing position; we can look at the last
two digits "35" and decide what to do with the "12".
TXR Programming Lanuage: http://nongnu.org/txr
Music DIY Mailing List: http://www.kylheku.com/diy
ADA MP-1 Mailing List: http://www.kylheku.com/mp1