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

newbie seeks inaccurate arithmetic insight

0 views
Skip to first unread message

Stanley Krute

unread,
Apr 29, 2001, 8:39:24 PM4/29/01
to
Hi

I just started on the Python learning path.

I tried some calculator stuff, and got this
sort of result:

http://static.userland.com/images/stanleydaily/pythonarithmetic.gif

I searched the Tutorial at http://www.python.org/doc/current/tut/tut.html
and the Reference manual at http://www.python.org/doc/current/ref/ref.html
for some discussion of why simple decimal arithmetic
gives these sorts of inaccurate results. But I couldn't find anything.

Can someone provide one or more URLs that
discuss the topic ??

Thanks

Stan


Tim Peters

unread,
Apr 29, 2001, 9:51:53 PM4/29/01
to pytho...@python.org
[Stanley Krute]

> I just started on the Python learning path.
>
> I tried some calculator stuff, and got this sort of result:
>
> http://static.userland.com/images/stanleydaily/pythonarithmetic.gif
>
> ...

> Can someone provide one or more URLs that discuss the topic ??

Most decimal fractions aren't exactly representable in binary floating point.
Not unique to Python; same story in C, C++, Java, Perl, Fortran, etc. See

http://www.python.org/cgi-bin/moinmoin/RepresentationError

for details.

If you need exact decimal arithmetic, and can afford the expense of
simulating decimal arithmetic, your best bet for now in Python is to use the
FixedPoint class at

ftp://ftp.python.org/pub/python/contrib-09-Dec-1999/
DataStructures/FixedPoint.py

Else you simply have to live with that binary floats are just approximations
(but good ones) to decimal fractions.

if-you-want-exact-buy-a-one-dollar-hand-calculator<wink>-ly y'rs - tim


Eric Renouf

unread,
Apr 29, 2001, 11:22:22 PM4/29/01
to
It's all in how the numbers are converted to a string. Quoting from the
What's New In Python 2.0 page at
http://www.python.org/2.0/new-python.html.

"""
Taking the repr() of a float now uses a different formatting precision
than str(). repr() uses %.17g format string for C's sprintf(), while
str()
uses %.12g as before. The effect is that repr() may occasionally show
more decimal places than str(), for certain numbers. For example, the
number 8.1 can't be represented exactly in binary, so repr(8.1) is
'8.0999999999999996', while str(8.1) is '8.1'.
"""

--
Eric Renouf
Software Engineer
Opticom Inc.
www.getiview.com

David LeBlanc

unread,
Apr 29, 2001, 11:46:01 PM4/29/01
to
In article <0v2H6.791$KM6.66...@twister2.starband.net>,
Stanle...@starband.net says...
<tongue_in_cheek>
Inacurate arithmetic isn't hard at all: just add (or subtract or multiply
or divide) an additional number of your choice!
</tongue_in_cheek>

Who WAS that masked man!

Stanley Krute

unread,
Apr 30, 2001, 9:31:18 AM4/30/01
to
Hi Tim

> Not unique to Python; same story in C, C++, Java, Perl, Fortran, etc.

Hmmm. Here's a corresponding c program

http://static.userland.com/images/stanleydaily/carithmeticprogram.gif

and here's its output

http://static.userland.com/images/stanleydaily/carithmetic.gif

Thanks for the link.

> If you need exact decimal arithmetic, and can afford the expense of
> simulating decimal arithmetic, your best bet for now in Python is to use
the
> FixedPoint class at
>
>
ftp://ftp.python.org/pub/python/contrib-09-Dec-1999/DataStructures/FixedPoin
t.py
>

Thanks again for the link.

> if-you-want-exact-buy-a-one-dollar-hand-calculator

<hehehehe>

stan

Fredrik Lundh

unread,
Apr 30, 2001, 11:41:04 AM4/30/01
to
Stanley Krute wrote:
> Hmmm. Here's a corresponding c program
>
> http://static.userland.com/images/stanleydaily/carithmeticprogram.gif

try using "%.17g" (show all significant digits) instead of "%f" (fudge it)

...or use "print" in Python, to get str() instead of repr() behaviour:

>>> 0.1
0.10000000000000001
>>> print 0.1
0.1

Cheers /F


Stanley Krute

unread,
Apr 30, 2001, 12:56:16 PM4/30/01
to
Hi Fredrik

> try using "%.17g" (show all significant digits) instead of "%f" (fudge it)

Aha ! Python defaults to Truth !

Verifying: Here's my c output using %.17g :

http://static.userland.com/images/stanleydaily/carithmetic17g.gif

The inaccuracies exist 15 or so places to the
right of the decimal point.

In the Python test


http://static.userland.com/images/stanleydaily/pythonarithmetic.gif

the inaccuracies also exist 15 or so places to the right of the decimal
point. Interestingly, in this particular test case, because the answers run
beneath the ideal, the inaccuracies propagate their visibility to just 2 or
3 places to the right
of the decimal point.

> ...or use "print" in Python, to get str() instead of repr() behaviour:

Thanks for the tip !

Stan
just newbying along ....

Tim Peters

unread,
Apr 30, 2001, 7:35:10 PM4/30/01
to pytho...@python.org
[/F]

> > try using "%.17g" (show all significant digits) instead of "%f"
> (fudge it)

[Stanley Krute]


> Aha ! Python defaults to Truth !

Nope: repr(float) gives a closer *approximation* to machine truth than does
str(float), and just *enough* of the truth so that eval(repr(x)) == x. In
general, you cannot rely on eval(str(x)) == x (in fact, it's unusual to get
the same float back if you go thru str() conversion first). If you wanted
the full truth, then e.g. you would get this instead:

>>> 0.1
0.1000000000000000055511151231257827021181583404541015625
>>>

That very long decimal number is the exact value of the binary approximation
to 0.1 stored in the machine by your HW -- and assuming that your platform C
library does best-possible conversion of the string "0.1" to an IEEE-754
double precision number to begin with.

> ...


> The inaccuracies exist 15 or so places to the right of the decimal
> point.

In general, since there 53 bits of precision in an IEEE-double, the tiniest
errors creep into the 53rd significant bit. An error of 1 in 2**53 is an
error of 1 in 10**x, for *some* value of x. A little math reveals x =
log10(2**53) = 53 * log10(2)

>>> import math
>>> 53 * math.log10(2)
15.954589770191003
>>>

So when viewed as decimal again, even the tiniest error will show up in the
15th or 16th significant decimal digit. Since that's what you've already
observed, you have reason to believe it <wink>.

it's-not-insane-but-it-is-maddening-ly y'rs - tim


Stanley Krute

unread,
May 1, 2001, 2:30:22 PM5/1/01
to
> Here is a URL that describes the situation. The context is Fortran,
> but the language makes no difference:
>
> http://www.lahey.com/float.htm

Thanks, Michael, for the most-excellent link !

Stan


Stanley Krute

unread,
May 1, 2001, 2:17:33 PM5/1/01
to
Thanks Tim for the excellent little essay.


0 new messages