
Boost : 
From: George A. Heintzelman (georgeh_at_[hidden])
Date: 20010509 12:48:31
I've often thought about writing this data type myself, so I would be
very interested in seeing it in boost.
> If there's interest, I'd like to do a reference implementation
> under the auspices of Boost. The requirements for the type
> would be:
>
>  A template class with the template parameter being the number
> of digits to the right of the decimal point.
>
>  Represent at least 18 decimal digits exactly. (The 18 comes
> from prior art on IBM mainframes, and also turns out to be
> convenient if the internal representation is a 64bit int.)
Note that not all platforms support 64bit ints directly. So you'll
have to do some work if you want to support 32bit machines with this
requirement.
>  Support all operations that can be done on ints except implicit
> conversions and nondecimal I/O.
Yes, and you must be able to do binary operations with all numeric
types without having to do explicit type conversions; using a
float/double operand should give a float/double result, otherwise you
should get a fixedpoint result. Note that supplying int versions and
not supplying double versions could give surprising results:
fixed<2> n(14,23); // Say this is the constructor for 14.23
cout << n * 2.3; // 28.46 or 32.729?
If you only supply fixed operator*(fixed,int), this will give you
something very different from what was probably wanted.
>  All operations are exact if there is no overflow and if no
> rounding is required. Overflow is undefined behavior.
> Rounding is done the way accountants do it: round to nearest
> with 1/2LSB always rounded "up." (I think "up" means "away
> from zero." I've asked an accountant friend via email but
> haven't yet gotten an answer.)
Accountants often do not round this way. They do what is known as the
banker's round, rounding an exact 1/2 LSB to the nearest even digit in
the higher place. This is to avoid, on the average, biases arising from
consistently rounding exact 1/2's (which happen frequently in finance)
'up' or 'down'. I think this rounding behavior would be a good choice
for this class.
>  Construction from const char* for faking decimal constants.
Interesting idea, but it should be an explicit constructor, and
presumably would be computationally expensive compared to building an
int or float from a constant, unless the compiler managed to optimize
it away (seems unlikely). So, I'd also be interested in other ways of
building it. For example:
typedef fixed<2> Money;
Money wallet(12,53); // Puts $12.53 in my wallet.
vector<Money> accounts(20,Money(252,20)); // Every player starts with
$252.20.
This would presumably give undefined results if the mantissa were
greater than 10^ndigits1. I suspect that this kind of constructor,
which is just going to have a few inlined arithmetic operations, will
be easier for a compiler to optimize away into a fixed constant int
internally.
>  Explicit conversion to/from double.
>
> Are there more requirements that I haven't thought of?
Make sure that fixed<0> also works transparently (and doesn't append a
trailing radix character by default...). I don't want to have to
specialcase currencies when I'm working in yen instead of pounds &
pence.
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