From: Andrew M. <an...@bu...> - 2002-03-02 18:16:24
|
On 2 Mar 2002, Konrad Hinsen wrote: > Tim Peters <ti...@co...> writes: > > > > # 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 > > I just tested and found the same behaviour, on RedHat Linux 7.1 > running on a Pentium machine. Python 2.1, compiled and running on the > same machine, returns 0. So does the Python 1.5.2 that comes with the > RedHat installation. Although there might certainly be something wrong > with the C compiler and/or header files, something has likely changed > in Python as well in going to 2.2, the only other explanation I see > would be a compiler optimization bug that didn't have an effect with > earlier Python releases. Other examples... FreeBSD 4.4: Python 2.1.1 (#1, Sep 13 2001, 18:12:15) [GCC 2.95.3 20010315 (release) [FreeBSD]] on freebsd4 Type "copyright", "credits" or "license" for more information. >>> 1e-200**2 0.0 >>> 1e200**2 Inf Python 2.3a0 (#1, Mar 1 2002, 00:00:52) [GCC 2.95.3 20010315 (release) [FreeBSD]] on freebsd4 Type "help", "copyright", "credits" or "license" for more information. >>> 1e-200**2 0.0 >>> 1e200**2 Traceback (most recent call last): File "<stdin>", line 1, in ? OverflowError: (34, 'Result too large') Both builds built with "./configure --with-fpectl", although the optimisation settings for the 2.3a0 (CVS of yesterday) build were tweaked (2.1.1: "-g -O3"; 2.3a0: "-s -m486 -Os"). My 2.2 OS/2 EMX build (which uses gcc 2.8.1 -O2) produces exactly the same result as 2.3a0 on FreeBSD. -- Andrew I MacIntyre "These thoughts are mine alone..." E-mail: an...@bu... | Snail: PO Box 370 an...@pc... | Belconnen ACT 2616 Web: http://www.andymac.org/ | Australia |
From: Tim P. <ti...@co...> - 2002-03-04 08:41:16
|
A lot of this speculation should have been cut short by my first msg. Yes, something changed in 2.2; follow the referenced link: http://sf.net/tracker/?group_id=5470&atid=105470&func=detail&aid=496104 For the rest of it, it looks like the "1e-200**2 raises OverflowError" glitch is unique to platforms using glibc. What isn't clear is whether it's dependent on which version of glibc, or on whether Python is linked with -lieee, or both. Unfortunately, the C standard (neither one) isn't a lick of help here -- error reporting from C math functions is a x-platform crapshoot. Can someone who sees this problem confirm or deny that they link with -lieee? If they see this problem and don't link with -lieee, also please try linking with -lieee and see whether the problem goes away then. On boxes with this problem, I'm also curious what import math print math.pow(1e-200, 2.0) does under 2.1. One probably-relevant thing that changed between 2.1 and 2.2 is that float**int calls the platform pow(float, int) in 2.2. 2.1 did it with repeated multiplication instead, but screwed up endcases. An example under 2.1: >>> x = -1. >>> import sys >>> x**(-sys.maxint-1L) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: negative number cannot be raised to a fractional power >>> The same thing under 2.2 returns 1.0, provided your platform pow() isn't braindead. Repeated multiplication is also less accurate than a decent-quality pow(). |
From: Tim P. <ti...@co...> - 2002-03-06 00:50:16
|
[Huaiyu Zhu] > ... > 1. The -lieee is indeed the most direct cure. On the specific platform tried. The libm errno rules changed between C89 and C99, and I'm afraid there's no errno behavior Python can rely on anymore. So I expect more changes will be needed in Python, regardless of how things turn out on this specific platform. > ... > 2. Is there a configure option to guarantee -lieee? If anyone can answer this question, please don't answer it here: it will just get lost. Attach it to Huaiyu's bug report instead: <http://sf.net/tracker/?func=detail&aid=525705&group_id=5470&atid=105470> Thanks. > ... > 3. errno 34 (or -lieee) may not be the sole reason. > > On a RedHat 6.1 upgraded to 7.1 (both gcc and glibc), errno 34 > is indeed raised in a C program linked without -lieee, and Python is > indeed compiled without -lieee, but Python does not raise > OverflowError. I expect you're missing something. Skip posted the Python code before, and if errno gets set, Python *does* raise OverflowError: errno = 0; /* Skip forgot to post this line, and it's important */ ... ix = pow(iv, iw); ... if (errno != 0) { /* XXX could it be another type of error? */ PyErr_SetFromErrno(PyExc_OverflowError); return NULL; If you can read C, believe your eyes <wink>. What you may be missing is what an utter mess C is here. How libm behaves may depend on compiler options, linker options, global system flags, and even options set for other libraries you link with. > ... > 4. Is there an easier way to debug such problems? The cause was obvious to the first person (Skip) who stepped into Python to see what the code did on a platform where it failed. It's not going to be obvious to someone who doesn't. > 5. How is 1e200**2 handled? It goes through exactly the same code. > Since both 1e-200**2 and 1e200**2 produce the same errno all the time, > but Python still raises OverflowError for 1e200**2 when linked with > -lieee, there must be a separate mechanism at work. You're speculating from a false base: if platform pow(x, y) sets errno to any non-zero value, Python x**y raises OverflowError. What differs is when platform pow(x, y) does not set errno. In that case, Python synthesizes errno=ERANGE if the pow() result equals +- platform HUGE_VAL. > What is that and how can I override it? Sorry, you can't override it. > I know this is by design, but I think the design is dumb (to put it > politely). I won't get into an argument here. I'll write > up my rationale against this when I have some time. I'm afraid a rationale won't do any good. I'm in favor of supplying full 754 compatibility myself, but: A) Getting from here to there requires volunteers to design, implement, document, and test the code. Given the atrocious state of C's 754 story, and the subtlety of 754's requirements, this needs volunteers who are both 754 experts and platform C experts. That combination is rare. B) Python's floating-point users will never agree it's a good thing, so such a change requires careful backward compatibility work too. This isn't likely to get done by someone who characterizes the other side as "dumb (to put it politely)" <0.9 wink>. Note that the only significant floating-point code ever contributed to the Python core was the fpectl module, and its purpose is to *break* 754 "non-stop" exception semantics in the places Python happens to let them sneak through. > I do remember there being several discussions in the past, but I don't > remember any convincing argument for the current decision. Any URL > would be greatly appreciated, beside the one pointed by Tim. Which "current decision" do you have in mind? There is no design doc for Python's numerics, if that's what you're looking for. As the text at the URL I gave you said, much of Python's fp behavior is accidental, inherited from platform C quirks. |
From: Tim P. <ti...@co...> - 2002-03-09 05:17:35
|
I hope the bogus underflow problem is fixed in CVS Python now. Since my platform didn't have the problem (and still doesn't, of course), we won't know for sure until people try it and report back. Python used to link with -lieee, but somebody changed it for a reason history may have lost. See comments attached to Huaiyu Zhu's bug report for more on that: <http://sf.net/tracker/?func=detail&aid=525705&group_id=5470&atid=105470> If someone on a box that had the problem can build current CVS Python with and without -lieee (I'm told it defaults to "without" today, although that appears to mixed up with whether or not __fpu_control is found outside of libieee (search for "ieee" in configure.in)), please try the following in a shell: import math x = 1e200 y = 1/x math.pow(x, 2) # expect OverflowError math.pow(y, 2) # expect 0. pow(x, 2) # expect OverflowError pow(y, 2) # expect 0. x**2 # expect OverflowError y**2 # expect 0. If those all work as annotated on a box that had the problem, please report the success *as a comment to the bug report* (link above). If one or more still fail, likewise please give box details and paste the failures into a comment on the bug report. Thanks! |
From: Jochen <jo...@un...> - 2002-03-20 01:09:54
|
The following message is a courtesy copy of an article that has been posted to comp.lang.python as well. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sat, 09 Mar 2002 00:17:40 -0500 Tim Peters wrote: Tim> I hope the bogus underflow problem is fixed in CVS Python now. Tim> Since my platform didn't have the problem (and still doesn't, of Tim> course), we won't know for sure until people try it and report Tim> back. Ok, looking at SourceForge and google this seems to be fixed in cvs HEAD. Would it be possible to put the same patch into the cvs python-2.2 branch, please? [1] Greetings, Jochen Footnotes: [1] If it is in there, it doesn't work for me with current python cvs branch release22-maint. I still have to manually add -lieee. (RedHat-7.0 with current updates.) - -- University of North Carolina phone: +1-919-962-4403 Department of Chemistry phone: +1-919-962-1579 Venable Hall CB#3290 (Kenan C148) fax: +1-919-843-6041 Chapel Hill, NC 27599, USA GnuPG key: 44BCCD8E -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6-cygwin-fcn-1 (Cygwin) Comment: Processed by Mailcrypt and GnuPG <http://www.gnupg.org/> iEYEARECAAYFAjyX4IAACgkQiJ/aUUS8zY52jgCbB69a8KZmCuk9MYIKzNu7EpBR 3fIAmQEYH1/ipB7OoiBcBPIAHev3dRlU =5l6n -----END PGP SIGNATURE----- |