This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: e_pow.c bug
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: Steve Moshier <steve at moshier dot net>
- Cc: java-patches at gcc dot gnu dot org
- Date: Mon, 12 Apr 2004 11:16:43 -0400
- Subject: Re: e_pow.c bug
- References: <Pine.LNX.4.58.0404110939430.21214@moshier.net>
Steve Moshier wrote:
Math libraries copied from Sun Microsystem's fdlibm (www.netlib.org/fdlibm)
have a bug in the real power function, e_pow.c. The bug is that
pow(x,y) returns 0 when x is very close to -1.0 and y is very large.
The following test program (in C) prints
pow(1.0000000000000002e+00 4.5035996273704970e+15) = 2.7182818284590455e+00
pow(-1.0000000000000002e+00 4.5035996273704970e+15) =0.0000000000000000e+00
pow(9.9999999999999978e-01 4.5035996273704970e+15) = 3.6787944117144222e-01
pow(-9.9999999999999978e-01 4.5035996273704970e+15) = 0.0000000000000000e+00
which is incorrect for the negative arguments raised to an odd integer
power.
Interesting. It looks like our StrictMath.java, which is a port of the C
code, also suffers from this problem. As does Sun's JRE as of 1.5-beta,
from looking at the following test case. Any idea if this issue has been
reported to Sun?
Bryce
public class PowTest
{
public static void main(String[] args)
{
math();
System.out.println("--");
strictmath();
}
static void strictmath()
{
double x, y, z;
x = 1.0 + StrictMath.pow (2.0, -52.0);
y = 1.0 + StrictMath.pow (2.0, 52.0);
z = StrictMath.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = -x;
z = StrictMath.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = 1.0 - StrictMath.pow (2.0, -52.0);
z = StrictMath.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = -x;
z = StrictMath.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
}
static void math()
{
double x, y, z;
x = 1.0 + Math.pow (2.0, -52.0);
y = 1.0 + Math.pow (2.0, 52.0);
z = Math.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = -x;
z = Math.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = 1.0 - Math.pow (2.0, -52.0);
z = Math.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
x = -x;
z = Math.pow (x, y);
System.out.println ("pow (" + x + " " + y + ") = " + z);
}
}