Boost logo

Boost :

From: Moore, Paul (paul.moore_at_[hidden])
Date: 2000-11-28 06:33:29


From: d.frey_at_[hidden] [mailto:d.frey_at_[hidden]]
> Sounds like work, right? :) But we will have no operator>>, no
> lexical_cast, nada - if there is no such beast as a floating point
> parser.

Yes, but we already have such a beast:
    double d;
    std::cin >> d;

However, because of representation inaccuracies, it does not produce an
*exact* representation of the input (eg, in the case of input 0.1). Hence,
to produce a rational, we have two options: one, to reimplement the parser
avoiding the inaccuracies (which I have no intention of doing), or two, to
create rationals from doubles, "undoing" the inaccuracy of parsing.

Put that way, option (2) sounds unreasonable. Maybe it is. (It's effectively
attempting to invert a lossy conversion). But if so, then I will not
implement a conversion from double to rational.

Don't get me wrong - any number of *functions* to convert doubles to
rationals can be implemented. Without needing access to the internals of the
rational class. The only question is whether one of these functions is
suitable for use as the default way of converting a double to a rational. In
my view, suitability boils down to "do what I mean". If the result of
rational<int> r = d surprises the user, then it has failed its purpose, and
should be handled via functional notation (where the function documentation
can include all the caveats).

FWIW, my current criteria for "not being surprising" is that

    for (int i = -100; i <= 100; ++i) {
        for (int j = 1; j <= 100; ++j) {
            rational<int> r = (static_cast<double>(i) /
static_cast<double>(j));
            assert (i == r.numerator());
            assert (j == r.denominator());
        }
    }

should not assert.

Dave's algorithm using continued fractions is the best bet so far. But in
order for it to work, I need to be able to portably detect overflow in
integer types. [[Actually, I've just thought of another problem - if
rational<T> is used where T is a user-defined unlimited precision integer
type, the conversion may never terminate!]]

I'll keep trying, because I do accept that initialising rationals from
doubles is something that users want to do. But I would rather document that
there is no such converstion, than implement something which contains
surprises. If people are happy with floating point representation issues,
then exact rationals are not what they should be using...

Paul.


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