Using fractions instead of floats
Robert Kern
robert.kern at gmail.com
Tue Oct 2 19:26:59 EDT 2007
mensanator at aol.com wrote:
> On Oct 2, 1:12 am, Robert Kern <robert.k... at gmail.com> wrote:
>> mensana... at aol.com wrote:
>>> How does gmpy make the conversion from float to rational?
>> gmpy has a configurable transformation between floats and the internal
>> representation. I believe the default goes through str().
>
> How do you do that? Is it configurable at run time or something that
> has to be done when compiled?
Run-time. Use gmpy.set_fcoform(). There is documentation:
http://gmpy.googlecode.com/svn/trunk/doc/gmpydoc.txt
However, it appears I was wrong about the default. The default will simply
extract the C double and call mpf_set_d() on it to convert it to the appropriate
internal mpf format. This faithfully gives:
In [26]: gmpy.mpf(0.6)
Out[26]: mpf('5.9999999999999998e-1')
The real conversion to mpq rational numbers takes place in using gmpy.f2q():
In [28]: gmpy.f2q?
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
Namespace: Interactive
Docstring:
f2q(x[,err]): returns the 'best' mpq approximating x to
within relative error err (default, x's precision); 'best'
rationals as per Stern-Brocot tree; mpz if denom is 1.
If err<0, error sought is 2.0 ** err.
In [44]: d = gmpy.mpf(0.6)
In [45]: d
Out[45]: mpf('5.9999999999999998e-1')
In [46]: d.getrprec()
Out[46]: 53
In [47]: gmpy.f2q(d)
Out[47]: mpq(3,5)
In [48]: gmpy.f2q(d, -53)
Out[48]: mpq(3,5)
In [49]: gmpy.f2q(d, -54)
Out[49]: mpq(3,5)
In [50]: gmpy.f2q(d, -55)
Out[50]: mpq(6002194384070353L,10003657306783922L)
The procedure followed here finds mpq(3,5) because evaluating "3.0/5.0" in as
binary floating point numbers in double precision gives you the same thing as
evaluating "0.6". So mpq(3,5) is the most parsimonious rational number
*approximating* Python's float("0.6") to within the default double-precision of
binary floating point arithmetic. However, float("0.6") is a rational number
that has the precise value of mpq(6002194384070353L,10003657306783922L).
> But it is still wrong to say "0.6 is definitely not the same as 3/5".
In the context in which it was said, I don't think it's wrong though it is
incomplete and confusing if taken out of that context.
> One can say 0.6 doesn't have an exact float representation and that
> inexact representation is not the same as 3/5. And I suppose one can
> be surprised that when this inexact representation is coerced to a
> rational the result is now exact.
>
> Would that be a fairer way of putting it?
Yes.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list