Boost logo

Boost :

From: Herve Bronnimann (hbr_at_[hidden])
Date: 2000-10-20 15:28:41


On Thu, Oct 19, 2000 at 09:42:35AM +0100, Moore, Paul wrote:
> > Also, suppose I want to convert the number to a
> > double? Is there a way to do that?
>
> rational_cast<double>(rat)

Isn't there a numeric_cast<> in boost which checks for overflows and all
these sorts of things? Wouldn't it be possible to interface numeric_cast
and rational<>, if rational is implemented in boost? Actually, it's
still in beta, and I'm not sure it fits in the framework, but the
concept is already there. Just asking.

Another thought: there could be also a natural conversion
from rational<> to interval<> which would address some concerns about
loss of precision. That's somehow related to Paul's concerns below.

> Just to clarify the internal representation issue a bit more (it's mentioned
> briefly in the documentation :-), the problem which arises is with the
> granularity of the representation. Assume we have a 32-bit int, and we are
> looking at rational<int>. Then the smallest representable positive rational
> is 1/0x7FFFFFFF. Hence, "rational-eps" is 1/0x7FFFFFFF. But, at the top end
> of the range, "rational-max" is 0x7FFFFFFF/1, and the next lower
> representable rational is 1 less (0x7FFFFFFE/1). This varying-precision
> dependent upon magnitude behaviour is normal with floating point
> representations, but it is well known that floatingh point arithmetic is
> "hard" to get right, and I would argue that that is *not* what the average
> user would expect of a rational class (after all, rationals are "exact
> fractions", aren't they?).

There is a whole field of number theory devoted to that (I think a
keyword is Farey series). But back to the discussion: std::complex<NT>
is supposed to be a wrapper around the number type NT, and it's clear
that complex will only be as good in precision as NT. Since rational is
NOT a number type, but a wrapper around a number type, just as complex,
it will inherit the properties of its base type.

My point is that if you want rational<int>, then you should be aware
that this is not an exact type. But int itself is not an exact type,
because of its limited range. So users who want "exact fraction" should
use a base type NT which is exact.

This is easily documentable and it draws an easy line between the
responsabilities of rational<> and those of NT.

> There is no way to build a truly exact rational from a limited-range integer
> (one of the reasons I'd like to see a bigint class in boost is that
> rational<bigint> is the natural rational number representation)

My point is that I don't think at all of rational<bigint> as the
"natural" rational number representation. There are zillions of bigint
representations available, including high-quality easily accessible
implementations like GMP and CLN, LEDA, CORE, you name it.
I don't see why such a type should be in boost or in any general purpose
library. Once you want exact (infinite precision) integers, you probably
want to use them to justify the overhead, so they probably will be large.
You have to think about using Karatsuba multiplication etc, in short,
you know where the road starts but not where it ends. It's a BIG
endeavor. I think you have to know what you're up against.

I think the class template rational<> can be quite useful even without
the presence of a bigint type. It certainly complements std::complex and
boost::interval very nicely.
Cheers,

-- 
Hervé

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