
Boost : 
From: Moore, Paul (Paul.Moore_at_[hidden])
Date: 19991203 09:34:28
Hi,
I was amazed to find that there isn't a basic rational numbers class
available anywhere on the net. It strikes me as pretty fundamental, like
complex.
Attached is a first draft of such a beast. The file implements
template <class Int> Int gcd(Int n, Int m)
template <class Int> Int lcm(Int n, Int m)
template <class Int> class rational { ... }
The gcd/lcm functions are there as convenience  I needed GCD for the
rational implementation, and LCM is trivial based on GCD.
The rational class is parameterised on an integer type (similar to complex)
so you can have rational<int>, rational<unsigned int>, rational<long long>,
or whatever.
Implementation details:
1. Rationals are stored as normalised (numerator, denominator) pairs. This
has
the advantage of simplicity. I don't see the normalisation cost as
critical, but
I'm willing to listen to arguments.
2. As a consequence, range is limited, in a fairly complex way. In a 32bit
setup,
unsigned rationals with denominator of 1 can go up to 2^32  1, whereas
with
a denominator of 2^32  1, they can only reach 1. An alternative
implementation
would be integer part plus fraction, but is this worth it?
I would appreciate comments. In particular 
1. Zero denominators throw an error  a placeholder string for now. Is there
a boost
policy on what to throw? Should I throw a subclass of std::exception?
[Actually,
I could implement infinity and NaN, but is this worth it? It makes
problems for
comparability, apart from anything else...]
2. The only implicit conversions I have are baseintegertype to rational.
Is this OK?
Does this cover things well enough?
3. I implement input and output operators. This pulls in the <iostream>
header. Is this
correct? Is it the right approach?
4. I expose numerator() and denominator() member functions. Is this a good
thing?
What other issues need considering? How about a to_float (to_double)
function? What
about from_float/from_double? Is there a good algorithm for the latter?
Other functions?
pow? modulus? ....?
The intention is that this should be a relatively lightweight value class
for people who want to use (exact) fractions, but who don't expect to do any
really heavy numerical processing. As such, I don't think it needs to get
too complicated. [But this is the root of my concern about the effective
range of the type above  can I describe this well enough to make sense to
class users?]
I ought to point out that I've not designed a valuebased class like this
before  I hope I haven't made any basic mistakes! On that note, would it be
useful to have a boost "samples" directory  containing template
implementations of concepts which can be fleshed out for real cases. I
imagine a basic numeric type (reimplementing int, say), a trivial smart
pointer, and a basic STL container (encapsulate a C array, maybe, or just a
null container which never contains anything), as a starter.
Hope this is of interest,
Paul Moore
<<rational.hpp>>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk