Using fractions instead of floats

Robert Kern robert.kern at gmail.com
Tue Oct 2 08:12:49 CEST 2007


mensanator at aol.com wrote:
> On Oct 1, 8:17?pm, richy... at gmail.com wrote:
>> On Oct 1, 9:03 pm, "mensana... at aol.com" <mensana... at aol.com> wrote:
>>
>>> On Oct 1, 7:20 pm, richy... at gmail.com wrote:
>>>> On Oct 1, 8:30 am, Nick Craig-Wood <n... at craig-wood.com> wrote:
>>>>>   >>> mpq(1,3)+0.6
>>>>>   mpq(14,15)
>>>> Golly!  That's quite impressive.  And more than a little bit magic as
>>>> well, since 0.6 is definitely not the same as 3/5.  
>>> It's not? Since when?
>> The 0.6 above is a floating point number, mathematically very close to
>> 0.6 but definitely not equal to it, since 0.6 can't be represented
>> exactly as a float.
> 
> Oh, you mean something like this, right?
> 
>>>> import gmpy
>>>> a = 0.6
>>>> a
> 0.59999999999999998
> 
> So, the rational should have 59999999999999998
> in the neumerator and 100000000000000000 in the
> denominator?

Actually (5404319552844595 / 2**53) would be best.

> But it doesn't
> 
>>>> b = gmpy.mpq(a)
>>>> b
> mpq(3,5)
> 
> Why do you suppose that is?

For the same reason that str() does. See below.

> For that matter, why
> does
> 
>>>> str(a)
> '0.6'
> 
> give me an EXACT representation?

It doesn't. It just rounds at a lower number of decimal places than is necessary
to faithfully represent the number. str() is intended to give friendly results,
not strictly correct ones. In this case it happens that float(str(0.6)) == 0.6,
but this is not guaranteed. For most numbers that a user or programmer might
enter, there will only be a relatively small amount of precision necessary, and
float(str(x)) == x will tend to hold. That's why it does this.

> Didn't you just
> say it couldn't be represented exactly?

Yup.

> Which is correct,
> 
>>>> str(a)
> '0.6'
> 
> or
> 
>>>> repr(a)
> '0.59999999999999998'
> 
> ?

The latter.

> 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().

-- 
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