Inexact representation cases (Re: Against PEP 240)

Tim Peters tim.one at home.com
Sun Jun 3 18:52:53 EDT 2001


[Tim]
> It turns out that the closest you can get in IEEE double is
>
>     1.1 ~= 2476979795053773 / 2**51
>
> which is, as a *decimal* number, *exactly*
>
>     1.100000000000000088817841970012523233890533447265625


[Michael Hudson]
> How did you get these numbers?

In a way that won't help you <wink>:

>>> import sys
>>> sys.path.insert(0, "/MyPy")
>>> from Rational import Rat, Format
>>> x = Rat.Rat("1.1").round(format=Format.IEEE_double)
>>> print x.cvt_exact(10)
1.100000000000000088817841970012523233890533447265625
>>>

Rational is a large package for doing rational arithmetic that also happens
to know all about floating-point formats with arbitrary bases and
precisions, and does best-possible conversions among any combination with
oodles of rounding options.  Given the number of times I'm elected to answer
these questions, writing it was a necessity <wink>.  Alas, writing docs
wasn't, and the API is incomprehensible unless you're me, so I never
distributed it.

> I'm sure you posted the routine a week or so back, but I can't dig
> it out of google.

I see Aahz pointed you to his Decimal package, which contains a much simpler
and self-contained function for this trivial task <wink>.

> I want to write a sys.displayhook that prints floats exactly, just for
> extra geekiness value.

It's not always, well, *illuminating":

>>> print Rat.Rat(1e-300).cvt_exact(10)
0.000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000100000000000000002505909
18352087596856961468077037052499253423199004660431840514846763028
12181950100894962306270278254148910311464998804130812246091606190
18271942662793458427551041478278701507022263926060379361392435977
50940301438661414791255135908825910173416922229212204049186218220
29155619541859418525883262040928316317872050154019969866169489804
10676557942431921652541808732242554300585073938340203330993157646
46743363847906553166172481259959859490629378249375961717786188879
29704765305423351347104182296375666379507674971478542365897951520
44892049176025289756709261767081824924720105632337755616538050643
65381258305022465963115930056323650792902539887815381155401398600
95879780811674328049363596311404191532834495603765390114858746528
62548828125
>>>

The result there may actually vary across platforms, depending on how good a
job the platform C does on converting "1e-300" to a double.  To get the best
possible (implying platform-independent!) result requires letting
string->double be handled by Python too:

>>> print Rat.Rat("1e-300").round(format=Format.IEEE_double).cvt_exact(10)
[happens to print the same thing in this case, under Windows]





More information about the Python-list mailing list