Boost logo

Boost :

From: Reggie Seagraves (reggie_at_[hidden])
Date: 2000-11-27 13:00:41


I previously sent (and am again enclosing here) an algorithm
for converting a floating point value to a rational. This
could/should be used by a rational class's constructor.
Please integrate/test it at your convenience.

        Thanks,

                Reggie

At 9:16 AM +0000 11/22/00, Moore, Paul wrote:
>From: John (EBo) David [mailto:ebo_at_[hidden]]
>> When playing with the rationals some more I ran across another bug.
>> When initializing a rational from a floating point number, the value
>> is auto-casted to IntType and produces erroneous results. For
>> example:
>>
>> int main ()
>> {
>> rational <int> tr;
>>
>> td = 1.5; tr = td;
>> std::cout << "rational " << tr;
>> std::cout << " cast " << boost::rational_cast<double>(tr);
>> std::cout << " original double " << td << std::endl;
>> }
>>
>> sets tr to be "1/1" and not "3/2"
>>
>> Is it reasonable to provide a rational constructor and/or assignment
>> with a floating point argument?
>
>It certainly is, in principle. The hard problem is how to convert a floating
>point value to a rational, in general. As far as I understand it, this is a
>non-trivial issue, especially if you want a "reasonable" answer. For
>example, given that 0.1 is not exactly representable in base 2, how confused
>would you be if
>
> rational<int> r = 0.1;
> cout << r;
>
>returned "1236517/12365171" (or something)???
>
>I believe that there are good algorithms for converting (inexact) floating
>point numbers to "reasonable" rationals. But I don't know what they are, nor
>am I competent to judge their effectiveness. If anyone could contribute some
>code for this, I'd be willing to integrate it.
>
>By the way, regardless of all this, I do agree that the existing behaviour
>is surprising almost to the point of being describable as a bug... But I
>don't see a good fix, short of the one I described above.
>
>> Somewhat related to this is the operator>> definition. Isn't it
>> reasonable to assume that the user defined input should not have to be
>> redefined to use the "nnn/ddd" syntax, but to behave as expected when
>> accepting floating point input?
>
>Same issue, to an extent. However, by parsing the floating point manually,
>it would be possible to read exact floats and store them as exact rationals.
>But I do not, personally, see that as entirely appropriate.
>
>The key point here (familiar to Scheme programmers...) is the distinction
>between "exact" and "inexact" numbers. Integers and rationals are "exact",
>whereas floats are "inexact". Conversions from exact to inexact can
>potentially lose information (this is not obvious to C programmers, where
>all of the exact representations convert without loss to the inexact types -
>but 64-bit platforms start to see this, where very large integers can't be
>represented exactly as floats, or even doubles). Conversions from inexact to
>exact can either be impossible (without truncation) or can give
>non-intuitive results - basically, the issue is that exact->inexact->exact
>is by no means certain of returning the original value.
>
>This is all very subtle stuff (as are the mathematical properties of machine
>floating point in general). It would be nice to get it right, but it's
>verging on being outside the design limits of the rational class (which is
>intended as a "simple" rational number solution).
>
>It's also related to the subtleties (hinted at in the documentation) of the
>accuracy limits of rational<T> when T is a limited-precision integer type...
>
>As I say, code accepted gratefully, but it's a bit beyond my competence to
>get it right by myself.
>Paul.





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