[SciPy-dev] bug in python 2.2/linux for numerical computations?

Fernando Perez fperez at pizero.colorado.edu
Sat Mar 2 10:16:54 CST 2002


Hi all,

this is a repost of something I saw today on c.l.p, but which seems of
interest to us. I tested it on a python 2.2 installation hand-built under
Mandrake 8.1 (gcc 2.96), same problem. It doesn't happen under windows xp
(py2.2 downloaded from python.org site).

Cheers,

f.

Original post:

Python 2.2 seriously crippled for numerical computation?

From:Huaiyu Zhu <huaiyu_zhu at yahoo.com>

Date:Saturday 02 March 2002 04:51:26

Groups:comp.lang.python

There appears to be a serious bug in Python 2.2 that severely limits its
usefulness for numerical computation:

# Python 1.5.2 - 2.1

>>> 1e200**2
inf
>>> 1e-200**2
0.0

# Python 2.2

>>> 1e-200**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')
>>> 1e200**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')

This produces the following serious effects: after hours of numerical
computation, just as the error is converging to zero, the whole thing
suddenly unravels.

Note that try/except is completely useless for this purpose.

I hope this is unintended behavior and that there is an easy fix.
Have any of you experienced this?  


Huaiyu


Tim Peter's response:

> There appears to be a serious bug in Python 2.2 that severely limits its
> usefulness for numerical computation:
>
> # Python 1.5.2 - 2.1
>
> >>> 1e200**2
> inf

A platform-dependent accident, there.

> >>> 1e-200**2
> 0.0
>
> # Python 2.2
>
> >>> 1e-200**2
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> OverflowError: (34, 'Numerical result out of range')

That one is surprising and definitely not intended:  it suggests your
platform libm is setting errno to ERANGE for pow(1e-200, 2.0), or that your
platform C headers define INFINITY but incorrectly, or that your platform C
headers define HUGE_VAL but incorrectly, or that your platform C compiler
generates bad code, or optimizes incorrectly, for negating and/or comparing
against its definition of HUGE_VAL or INFINITY.  Python intends silent
underflow to 0 in this case, and I haven't heard of underflows raising
OverflowError before.  Please file a bug report with full details about
which operating system, Python version, compiler and C libraries you're
using (then it's going to take a wizard with access to all that stuff to
trace into it and determine the true cause).

> >>> 1e200**2
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> OverflowError: (34, 'Numerical result out of range')

That one is intended; see

http://sf.net/tracker/?group_id=5470&atid=105470&func=detail&aid=496104

for discussion.

> This produces the following serious effects: after hours of numerical
> computation, just as the error is converging to zero, the whole thing
> suddenly unravels.

It depends on how you write your code, of course.

> Note that try/except is completely useless for this purpose.

Ditto.  If your platform C lets you get away with it, you may still be able
to get an infinity out of 1e200 * 1e200.

> I hope this is unintended behavior

Half intended, half both unintended and never before reported.

> and that there is an easy fix.

Sorry, "no" to either.

------------------------------
Paul Dubois just posted this a second ago:

I also see the underflow problem on my Linux box 2.4.2-2. This is
certainly untenable. However, I am able to catch OverflowError in both
cases. I had a user complain about this just yesterday, so I think it is
a new behavior in Python 2.2 which I was just rolling out. A small
Fortran test problem did not exhibit the underflow bug, and caught the
overflow bug at COMPILE TIME (!).

There are two states for the IEEE underflow: one in which the hardware
sets it to zero, and the other in which the hardware signals the OS and
you can tell the OS to set it to zero. There is no standard for the
interface to this facility that I am aware of. (Usually I have had to
figure out how to make sure the underflow was handled in hardware
because the sheer cost of letting it turn into a system call was
prohibitive.) I speculate that on machines where the OS call is the
default that Python 2.2 is catching the signal when it should let it go
by.

I have not looked at this lately so something may have changed. 

You can use the kinds package that comes with Numeric to test 
for maximum and minimum exponents. kinds.default_float_kind.MAX_10_EXP
(equal to 308 on my Linux box, for example) tells you how big an
exponent a floating point number can have. MIN_10_EXP (-307 for me) is
also there.

Work around on your convergence test: instead of testing x**2 you might
test log10(x) vs. a constant or some expression involving
kinds.default_float_kind.MIN_10_EXP.




More information about the Scipy-dev mailing list