Boost logo

Boost :

From: George A. Heintzelman (georgeh_at_[hidden])
Date: 2001-05-09 16:34:45


> Consider the sales tax use case:
>
> double rate1 = 1./3.;
> double rate2 = .051;
>
> fixed<2> subtotal(1, 23);
> fixed<2> tax1 = subtotal * rate1;
> fixed<2> tax2 = subtotal * rate2;
> fixed<2> total = subtotal + tax1 + tax 2;
>
> Observations:
>
> - The precision of the rate has no correlation to the precision of the
> currency, and moreover it is perfectly reasonable for a rate to use all
> the precision that the processor can handle, as in the 1/3 case. This
> leads to the temptation to perform the multiplication in floating point
> and then round back to fixed, but then an evenly divisible rate like .5
> of .1 might not come out right. Converting rate1 to a fixed seems to be
> the way to go, so long as it is a fixed<18> (or whatever the maximum
> size is).
>
> - To avoid the currencies-not-adding embarrassment, the calculation
> should return a fixed-point number, properly rounded off, even if this
> causes the total to not be equal to fixed<2>(1.23 * (1 + rate1 +
> rate2)).

The way you've written it above, you will get the sum of two rounded
quantities either way, as a resultant double is converted back to a
fixed<2>. If that's what is wanted, fine, everyone is happy, just write
the code that way and the roundings taking place are at least more
obvious if not crystal clear.

The real question is, given:

double rate1 = 1./3., rate2 = 0.51;
fixed<2> subtotal(1,23);

fixed<2> tax = subtotal * rate1 + subtotal*rate2;

what do you want it to return? The same thing as above, or what you
would get with

fixed<2> tax = subtotal * (rate1 + rate2);

(Okay, I know the second expression won't ALWAYS be the same given
floating point arithmetic, but a lot more often than it would be as
computed above; you'd have to work pretty hard to find a rounding edge
that made tax different in the double-returning case, for reasonably
sized doubles.)

I'd prefer the second; my experience has been that those implicit
roundings will bite you when you least expect them. If you want the
roundings, I'd rather see them written:

fixed<2> tax = fixed<2>(subtotal * rate1) + fixed<2>(subtotal * rate2);

This way you don't really need a comment as to why the code wasn't
written 'subtotal * (rate1 + rate2)' in the first place. The reason is
clear, and a maintenance programmer isn't going to screw it up.

George Heintzelman
georgeh_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk