Bug 369 - pow problems on x86
Summary: pow problems on x86
Alias: None
Product: glibc
Classification: Unclassified
Component: math (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2004-09-06 12:23 UTC by Zoltan Varga
Modified: 2019-04-10 15:07 UTC (History)
5 users (show)

See Also:
Host: i686-pc-linux-gnu
Last reconfirmed:
fweimer: security-

patch for pow to return inf/0 for (-2,+/-1E300) (612 bytes, patch)
2006-08-31 22:27 UTC, Pete Eberlein
Details | Diff
patch for pow to return inf/0 for (-2,+/-1E300) (604 bytes, patch)
2006-08-31 22:32 UTC, Pete Eberlein
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zoltan Varga 2004-09-06 12:23:45 UTC
Consider the following test program:
#include <stdio.h>
#include <math.h>

void main() {
        double d;

        d = pow (-2, 1E300);
        printf ("D: %f.\n", d);

        d = pow (-2, -1E300);
        printf ("D: %f.\n", d);

Under x86 linux, this prints out:

D: nan.
D: nan

I think the answer should be +inf and 0, respectively. Both
windows, and the IBM Accurate Portable Mathematical library
these values, so I think this might be a bug in the assembly
pow routine in glibc.
Comment 1 Andreas Jaeger 2004-12-18 15:37:04 UTC
The report is confirmed.  On other platforms we get the expected result.

Uli, could you look into this, please?
Comment 2 Steven Bosscher 2006-05-07 14:57:49 UTC
It seems I've run into this one now, too.  What happened to this bug?
Comment 3 Nikolay Zhuravlev 2006-06-15 09:17:10 UTC
I built glibc from CVS on 2006/06/14 and the bug is still there.
I think the culprit is the assembler code in __ieee754_pow.

POSIX wants HUGE_VAL for pow(-2, 1E300).
Comment 4 Nikolay Zhuravlev 2006-06-15 09:23:53 UTC
Changed version to 'unspecified' since it is in the trunk
Comment 5 Pete Eberlein 2006-08-31 22:27:03 UTC
Created attachment 1269 [details]
patch for pow to return inf/0 for (-2,+/-1E300)

I've created a patch to return inf for pow(-2,1E300) and 0 for pow(-2,-1E300). 
This patch modifies the function to use |x| and filter the result if x < 0,
keeping inf or zero, otherwise return NaN.
Comment 6 Pete Eberlein 2006-08-31 22:32:31 UTC
Created attachment 1270 [details]
patch for pow to return inf/0 for (-2,+/-1E300)

oops, fixing the diff since it had some control chars accidentally pasted into
the file.
Comment 7 Ismail "cartman" Donmez 2007-12-15 09:46:38 UTC
Still affects glibc 2.7
Comment 8 Michael Kerrisk 2008-07-30 09:17:06 UTC
Still present in glibc 2.8
Comment 9 Michael Kerrisk 2010-09-12 05:44:43 UTC
Still present in glibc 2.12.1, where we get:

D: -nan.
D: -nan.
Comment 10 Joseph Myers 2012-02-22 21:27:13 UTC
Still present.  Could one of our x86 experts review Pete Eberlein's patch from 2006?

Testcases are certainly needed for libm-test.inc for a fix to go in - both tests for the particular cases here, and tests for more normal cases of powers of negative numbers (negative number to small (+ve and -ve) even powers, negative number to small (+ve and -ve) odd powers).  Cases involving infinities and zeros as arguments seem better covered in the testsuite and there are already tests of negative numbers to fractional powers.
Comment 11 Paolo Bonzini 2012-03-22 23:21:04 UTC
The patch looks good to me from the x86 point of view, but I cannot really say anything about the math.
Comment 12 Joseph Myers 2012-03-27 16:02:37 UTC
The attached patch is incorrect (it results in NaN for pow (-1, DBL_MAX), which should be 1; an infinity for pow (-DBL_MAX, 1000.5), which should be NaN; zero for pow (-DBL_MIN, 1000.5), which should be NaN).  I'm working on a different patch.
Comment 13 Joseph Myers 2012-03-28 15:01:45 UTC
Fixed by:

commit d6270972f79fe89a96fa7a3909991dad2e317033
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Wed Mar 28 14:57:58 2012 +0000

    Fix pow of negative numbers to integer exponents (bugs 369, 2678, 3866).