Bug 369

Summary: pow problems on x86
Product: glibc Reporter: Zoltan Varga <vargaz>
Component: mathAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: bonzini, glibc-bugs, mtk.manpages, null, steven
Priority: P2 Flags: fweimer: security-
Version: unspecified   
Target Milestone: ---   
Host: i686-pc-linux-gnu Target:
Build: Last reconfirmed:
Attachments: patch for pow to return inf/0 for (-2,+/-1E300)
patch for pow to return inf/0 for (-2,+/-1E300)

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
solaris,
windows, and the IBM Accurate Portable Mathematical library
returns
these values, so I think this might be a bug in the assembly
language
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).