Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inexact representation cases (Re: Against PEP 240)

1 view
Skip to first unread message

Clark C . Evans

unread,
Jun 2, 2001, 11:28:25 AM6/2/01
to pytho...@python.org
On Thu, May 31, 2001 at 01:17:31AM -0400, Tim Peters wrote:
| >>> 1.1
| 1.1000000000000001
| >>> 7.35
| 7.3499999999999996

What is the general pattern for these types
of inexact represenatation?

Clark

Grant Edwards

unread,
Jun 2, 2001, 11:53:08 AM6/2/01
to

1/10 (base 10) is not representable in a finite base-2 number,
in the same way that 2/3 is not representable in a finite
base-10 number.

The same goes for 35/100

--
Grant Edwards grante Yow! I will establish
at the first SHOPPING MALL in
visi.com NUTLEY, New Jersey...

Clark C . Evans

unread,
Jun 2, 2001, 1:06:51 PM6/2/01
to pytho...@python.org
On Sat, Jun 02, 2001 at 03:53:08PM +0000, Grant Edwards wrote:
| >| >>> 1.1
| >| 1.1000000000000001
| >| >>> 7.35
| >| 7.3499999999999996
| >
| >What is the general pattern for these types of inexact
| >represenatation?
|
| 1/10 (base 10) is not representable in a finite base-2 number,
| in the same way that 2/3 is not representable in a finite
| base-10 number.
|
| The same goes for 35/100

*slaps hand against head and says "Duh!"*

Thanks!

Clark

Tim Peters

unread,
Jun 2, 2001, 4:13:51 PM6/2/01
to pytho...@python.org
[Clark C . Evans]

> >>> 1.1
> 1.1000000000000001
> >>> 7.35
> 7.3499999999999996
>
> What is the general pattern for these types
> of inexact represenatation?

Unsure what you're looking for. In general, a non-zero decimal number D is
exactly representable in a binary fp format if and only it can be written in
the form

D = I/2**J

for some (possibly large) integers I and J, and where the possible values of
I and J are constrained by how many bits the fp format devotes to them. For
IEEE-754 doubles (which is what a Python float becomes on most machines), it
must have 1 <= I < 2**53 (that is, I has no more than 53 bits), and the
range on J is roughly plus or minus 1000 (yes, it can be made exact, but who
cares <wink>).

So look at 1.1 == 11/10. Can that be written in the form I/2**J? If so,
then 11*2**J == 10*I too. 5 divides 10 evenly, so also divides 10*I. But
if 10*I == 11*2**J and 5 divides the left side, then 5 must also divide the
right side. But 5 doesn't divide 11 or 2**J, so can't (because 5 is prime)
divide their product evenly either. IOW, no matter how many bits you use,
1.1 can't be represented exactly in a binary fp format.

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

*Rounding* that to 17 significant decimal digits is where

1.10000000000000001

comes from in the display.

Similarly the best double approximation to 7.35 is

4137682157646643 / 2**49

which is exactly

7.3499999999999996447286321199499070644378662109375

in decimal, which rounds to

7.3499999999999996

for display. Note that the situation isn't symmetric: not every finite
decimal fraction is exactly representable as a finite base 2 fraction, but
every finite binary fraction *is* exactly representable as a finite base 10
fraction (if you start with I/2**J, just multiply top and bottom by 5**J to
get (I*5**J)/10**J). But afraid that's just another stumbling block at
first ...

Michael Hudson

unread,
Jun 3, 2001, 5:16:55 PM6/3/01
to
"Tim Peters" <tim...@home.com> writes:

> 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

How did you get these numbers? I'm sure you posted the routine a week
or so back, but I can't dig it out of google.

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

Cheers,
M.

--
If you have too much free time and can't think of a better way to
spend it than reading Slashdot, you need a hobby, a job, or both.
-- http://www.cs.washington.edu/homes/klee/misc/slashdot.html#faq

Aahz Maruch

unread,
Jun 3, 2001, 6:05:47 PM6/3/01
to
In article <m3ae3pb...@atrus.jesus.cam.ac.uk>,

Michael Hudson <m...@python.net> wrote:
>"Tim Peters" <tim...@home.com> writes:
>> 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
>
>How did you get these numbers? I'm sure you posted the routine a week
>or so back, but I can't dig it out of google.
>
>I want to write a sys.displayhook that prints floats exactly, just for
>extra geekiness value.

You can use Decimal.py (with its associated bugs) from
http://starship.python.net/crew/aahz/
--
--- Aahz <*> (Copyright 2001 by aa...@pobox.com)

Androgynous poly kinky vanilla queer het Pythonista http://www.rahul.net/aahz/
Hugs and backrubs -- I break Rule 6

I surf faster than you do, monkey boy. (My take on Netscape vs. Lynx)

0 new messages