*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

precision problem.

*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

rounding errors.

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

digits.

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