Boost logo

Boost :

From: Mickey Moore (mgmoore_at_[hidden])
Date: 2004-12-12 12:53:08


Andras Erdei <aerdei <at> gmail.com> writes:

> i think the documentation on boost::rational is
> misleading, and it cannot be used with finite
> precision (e.g. the built-in) types at all:
> whenever the result of an operation cannot be
> represented exactly, it returns something totally
> bogus

This is true for *any* operations on the built-in types. If you over/under-
flow, the results are meaningless.

> for example with rational<short> let's try to
> add 191/181 (=1.055...) and 197/193 (=1.021...)
> the exact result is 72520/34933 (=2.076...),
> and we get 6984/-30603 (=-0.229...)!

You didn't state what platform you were running on, but I figure it's likely
that shorts are 16 bits. Therefore both the numerator and denominator of the
result are out of range (greater than 32768), so there is no possible way that
rational<short> can represent this number. What can you expect it to do in
such case?

> i don't think the intended audience can "code in
> anticipation of such issues" (the task of determining
> when these issues come up has the same complexity as
> doing the actual arithmetic)

I will agree that it's much less obvious when you will get into trouble, since
the numbers were of modest magnitude -- though still greater than sqrt(32768)
which is a (very rough) indication of potential trouble. (And you did choose a
rare case, where all the numerators and denominators are prime numbers.)

In this case the obvious solution is rational<long>, but similar examples can
of course be created for it.

In general, you can never use finite precision and expect accurate results
without knowing something about the numbers you are using. That's true for all
finite precision types.

> fixing rational<> to work with finite precision integers
> so that for calculations like the above we get the best
> representable approximation (in this case 3197/1540 =
> 2.076, precise to 7 digits) is pretty straightforward
> -- the gcd() function implicitly calculates all
> representable approximations -- but would require
> rewriting the whole class

If someone wants the best approximation rather than the exact answer, they
would probably just be using floating point. rational is used when people want
an exact answer, not just an approximation.

I think it would be more useful to add a mechanism (probably optional) for
reporting when such overflows ocurred (or some equivalent to floating point
NANs and INFs, perhaps).

-- Mickey Moore


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