FastMath { public static double pow(double x, double y) { final double lns[] = new double[2]; if (y == 0.0) { return 1.0; } if (x != x) { return x; } if (x == 0) { long bits = Double.doubleToRawLongBits(x); if ((bits & 0x8000000000000000L) != 0) { long yi = (long) y; if (y < 0 && y == yi && (yi & 1) == 1) { return Double.NEGATIVE_INFINITY; } if (y > 0 && y == yi && (yi & 1) == 1) { return -0.0; } } if (y < 0) { return Double.POSITIVE_INFINITY; } if (y > 0) { return 0.0; } return Double.NaN; } if (x == Double.POSITIVE_INFINITY) { if (y != y) { return y; } if (y < 0.0) { return 0.0; } else { return Double.POSITIVE_INFINITY; } } if (y == Double.POSITIVE_INFINITY) { if (x * x == 1.0) { return Double.NaN; } if (x * x > 1.0) { return Double.POSITIVE_INFINITY; } else { return 0.0; } } if (x == Double.NEGATIVE_INFINITY) { if (y != y) { return y; } if (y < 0) { long yi = (long) y; if (y == yi && (yi & 1) == 1) { return -0.0; } return 0.0; } if (y > 0) { long yi = (long) y; if (y == yi && (yi & 1) == 1) { return Double.NEGATIVE_INFINITY; } return Double.POSITIVE_INFINITY; } } if (y == Double.NEGATIVE_INFINITY) { if (x * x == 1.0) { return Double.NaN; } if (x * x < 1.0) { return Double.POSITIVE_INFINITY; } else { return 0.0; } } if (x < 0) { if (y >= TWO_POWER_53 || y <= -TWO_POWER_53) { return pow(-x, y); } if (y == (long) y) { return ((long)y & 1) == 0 ? pow(-x, y) : -pow(-x, y); } else { return Double.NaN; } } double ya; double yb; if (y < 8e298 && y > -8e298) { double tmp1 = y * HEX_40000000; ya = y + tmp1 - tmp1; yb = y - ya; } else { double tmp1 = y * 9.31322574615478515625E-10; double tmp2 = tmp1 * 9.31322574615478515625E-10; ya = (tmp1 + tmp2 - tmp1) * HEX_40000000 * HEX_40000000; yb = y - ya; } final double lores = log(x, lns); if (Double.isInfinite(lores)){ return lores; } double lna = lns[0]; double lnb = lns[1]; double tmp1 = lna * HEX_40000000; double tmp2 = lna + tmp1 - tmp1; lnb += lna - tmp2; lna = tmp2; final double aa = lna * ya; final double ab = lna * yb + lnb * ya + lnb * yb; lna = aa+ab; lnb = -(lna - aa - ab); double z = 1.0 / 120.0; z = z * lnb + (1.0 / 24.0); z = z * lnb + (1.0 / 6.0); z = z * lnb + 0.5; z = z * lnb + 1.0; z *= lnb; final double result = exp(lna, z, null); return result; } private  FastMath(); static double sqrt(final double a); static double cosh(double x); static double sinh(double x); static double tanh(double x); static double acosh(final double a); static double asinh(double a); static double atanh(double a); static double signum(final double a); static float signum(final float a); static double nextUp(final double a); static float nextUp(final float a); static double nextDown(final double a); static float nextDown(final float a); static double random(); static double exp(double x); static double expm1(double x); static double log(final double x); static double log1p(final double x); static double log10(final double x); static double log(double base, double x); static double pow(double x, double y); static double pow(double d, int e); static double sin(double x); static double cos(double x); static double tan(double x); static double atan(double x); static double atan2(double y, double x); static double asin(double x); static double acos(double x); static double cbrt(double x); static double toRadians(double x); static double toDegrees(double x); static int abs(final int x); static long abs(final long x); static float abs(final float x); static double abs(double x); static double ulp(double x); static float ulp(float x); static double scalb(final double d, final int n); static float scalb(final float f, final int n); static double nextAfter(double d, double direction); static float nextAfter(final float f, final double direction); static double floor(double x); static double ceil(double x); static double rint(double x); static long round(double x); static int round(final float x); static int min(final int a, final int b); static long min(final long a, final long b); static float min(final float a, final float b); static double min(final double a, final double b); static int max(final int a, final int b); static long max(final long a, final long b); static float max(final float a, final float b); static double max(final double a, final double b); static double hypot(final double x, final double y); static double IEEEremainder(double dividend, double divisor); static int toIntExact(final long n); static int incrementExact(final int n); static long incrementExact(final long n); static int decrementExact(final int n); static long decrementExact(final long n); static int addExact(final int a, final int b); static long addExact(final long a, final long b); static int subtractExact(final int a, final int b); static long subtractExact(final long a, final long b); static int multiplyExact(final int a, final int b); static long multiplyExact(final long a, final long b); static int floorDiv(final int a, final int b); static long floorDiv(final long a, final long b); static int floorMod(final int a, final int b); static long floorMod(final long a, final long b); static double copySign(double magnitude, double sign); static float copySign(float magnitude, float sign); static int getExponent(final double d); static int getExponent(final float f); static void main(String[] a); static final double PI; static final double E; }
@Test public void testMath904() { final double x = -1; final double y = (5 + 1e-15) * 1e15; Assert.assertEquals(Math.pow(x, y), FastMath.pow(x, y), 0); Assert.assertEquals(Math.pow(x, -y), FastMath.pow(x, -y), 0); }
@Test public void testPowSpecialCases() { Assert.assertEquals("pow(-1, 0) should be 1.0", 1.0, FastMath.pow(-1.0, 0.0), Precision.EPSILON); Assert.assertEquals("pow(-1, -0) should be 1.0", 1.0, FastMath.pow(-1.0, -0.0), Precision.EPSILON); Assert.assertEquals("pow(PI, 1.0) should be PI", FastMath.PI, FastMath.pow(FastMath.PI, 1.0), Precision.EPSILON); Assert.assertEquals("pow(-PI, 1.0) should be -PI", -FastMath.PI, FastMath.pow(-FastMath.PI, 1.0), Precision.EPSILON); Assert.assertTrue("pow(PI, NaN) should be NaN", Double.isNaN(FastMath.pow(Math.PI, Double.NaN))); Assert.assertTrue("pow(NaN, PI) should be NaN", Double.isNaN(FastMath.pow(Double.NaN, Math.PI))); Assert.assertTrue("pow(2.0, Infinity) should be Infinity", Double.isInfinite(FastMath.pow(2.0, Double.POSITIVE_INFINITY))); Assert.assertTrue("pow(0.5, -Infinity) should be Infinity", Double.isInfinite(FastMath.pow(0.5, Double.NEGATIVE_INFINITY))); Assert.assertEquals("pow(0.5, Infinity) should be 0.0", 0.0, FastMath.pow(0.5, Double.POSITIVE_INFINITY), Precision.EPSILON); Assert.assertEquals("pow(2.0, -Infinity) should be 0.0", 0.0, FastMath.pow(2.0, Double.NEGATIVE_INFINITY), Precision.EPSILON); Assert.assertEquals("pow(0.0, 0.5) should be 0.0", 0.0, FastMath.pow(0.0, 0.5), Precision.EPSILON); Assert.assertEquals("pow(Infinity, -0.5) should be 0.0", 0.0, FastMath.pow(Double.POSITIVE_INFINITY, -0.5), Precision.EPSILON); Assert.assertTrue("pow(0.0, -0.5) should be Inf", Double.isInfinite(FastMath.pow(0.0, -0.5))); Assert.assertTrue("pow(Inf, 0.5) should be Inf", Double.isInfinite(FastMath.pow(Double.POSITIVE_INFINITY, 0.5))); Assert.assertTrue("pow(-0.0, -3.0) should be -Inf", Double.isInfinite(FastMath.pow(-0.0, -3.0))); Assert.assertTrue("pow(-Inf, -3.0) should be -Inf", Double.isInfinite(FastMath.pow(Double.NEGATIVE_INFINITY, 3.0))); Assert.assertTrue("pow(-0.0, -3.5) should be Inf", Double.isInfinite(FastMath.pow(-0.0, -3.5))); Assert.assertTrue("pow(Inf, 3.5) should be Inf", Double.isInfinite(FastMath.pow(Double.POSITIVE_INFINITY, 3.5))); Assert.assertEquals("pow(-2.0, 3.0) should be -8.0", -8.0, FastMath.pow(-2.0, 3.0), Precision.EPSILON); Assert.assertTrue("pow(-2.0, 3.5) should be NaN", Double.isNaN(FastMath.pow(-2.0, 3.5))); Assert.assertTrue("pow(+Inf, NaN) should be NaN", Double.isNaN(FastMath.pow(Double.POSITIVE_INFINITY, Double.NaN))); Assert.assertTrue("pow(1.0, +Inf) should be NaN", Double.isNaN(FastMath.pow(1.0, Double.POSITIVE_INFINITY))); Assert.assertTrue("pow(-Inf, NaN) should be NaN", Double.isNaN(FastMath.pow(Double.NEGATIVE_INFINITY, Double.NaN))); Assert.assertEquals("pow(-Inf, -1.0) should be 0.0", 0.0, FastMath.pow(Double.NEGATIVE_INFINITY, -1.0), Precision.EPSILON); Assert.assertEquals("pow(-Inf, -2.0) should be 0.0", 0.0, FastMath.pow(Double.NEGATIVE_INFINITY, -2.0), Precision.EPSILON); Assert.assertTrue("pow(-Inf, 1.0) should be -Inf", Double.isInfinite(FastMath.pow(Double.NEGATIVE_INFINITY, 1.0))); Assert.assertTrue("pow(-Inf, 2.0) should be +Inf", Double.isInfinite(FastMath.pow(Double.NEGATIVE_INFINITY, 2.0))); Assert.assertTrue("pow(1.0, -Inf) should be NaN", Double.isNaN(FastMath.pow(1.0, Double.NEGATIVE_INFINITY))); }