mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-10 02:18:46 +00:00
8136799: Port fdlibm cbrt to Java
Reviewed-by: bpb
This commit is contained in:
parent
c38b0eaba5
commit
655a976e65
@ -152,7 +152,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_StrictMath_log10;
|
||||
Java_java_lang_StrictMath_sin;
|
||||
Java_java_lang_StrictMath_sqrt;
|
||||
Java_java_lang_StrictMath_cbrt;
|
||||
Java_java_lang_StrictMath_tan;
|
||||
Java_java_lang_StrictMath_cosh;
|
||||
Java_java_lang_StrictMath_sinh;
|
||||
|
||||
@ -99,6 +99,64 @@ class FdLibm {
|
||||
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL)|( ((long)high)) << 32 );
|
||||
}
|
||||
|
||||
/**
|
||||
* cbrt(x)
|
||||
* Return cube root of x
|
||||
*/
|
||||
public static class Cbrt {
|
||||
// unsigned
|
||||
private static final int B1 = 715094163; /* B1 = (682-0.03306235651)*2**20 */
|
||||
private static final int B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
|
||||
|
||||
private static final double C = 0x1.15f15f15f15f1p-1; // 19/35 ~= 5.42857142857142815906e-01
|
||||
private static final double D = -0x1.691de2532c834p-1; // -864/1225 ~= 7.05306122448979611050e-01
|
||||
private static final double E = 0x1.6a0ea0ea0ea0fp0; // 99/70 ~= 1.41428571428571436819e+00
|
||||
private static final double F = 0x1.9b6db6db6db6ep0; // 45/28 ~= 1.60714285714285720630e+00
|
||||
private static final double G = 0x1.6db6db6db6db7p-2; // 5/14 ~= 3.57142857142857150787e-01
|
||||
|
||||
public static strictfp double compute(double x) {
|
||||
double t = 0.0;
|
||||
double sign;
|
||||
|
||||
if (x == 0.0 || !Double.isFinite(x))
|
||||
return x; // Handles signed zeros properly
|
||||
|
||||
sign = (x < 0.0) ? -1.0: 1.0;
|
||||
|
||||
x = Math.abs(x); // x <- |x|
|
||||
|
||||
// Rough cbrt to 5 bits
|
||||
if (x < 0x1.0p-1022) { // subnormal number
|
||||
t = 0x1.0p54; // set t= 2**54
|
||||
t *= x;
|
||||
t = __HI(t, __HI(t)/3 + B2);
|
||||
} else {
|
||||
int hx = __HI(x); // high word of x
|
||||
t = __HI(t, hx/3 + B1);
|
||||
}
|
||||
|
||||
// New cbrt to 23 bits, may be implemented in single precision
|
||||
double r, s, w;
|
||||
r = t * t/x;
|
||||
s = C + r*t;
|
||||
t *= G + F/(s + E + D/s);
|
||||
|
||||
// Chopped to 20 bits and make it larger than cbrt(x)
|
||||
t = __LO(t, 0);
|
||||
t = __HI(t, __HI(t) + 0x00000001);
|
||||
|
||||
// One step newton iteration to 53 bits with error less than 0.667 ulps
|
||||
s = t * t; // t*t is exact
|
||||
r = x / s;
|
||||
w = t + t;
|
||||
r = (r - t)/(w + r); // r-s is exact
|
||||
t = t + t*r;
|
||||
|
||||
// Restore the original sign bit
|
||||
return sign * t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hypot(x,y)
|
||||
*
|
||||
|
||||
@ -307,7 +307,9 @@ public final class StrictMath {
|
||||
* @return the cube root of {@code a}.
|
||||
* @since 1.5
|
||||
*/
|
||||
public static native double cbrt(double a);
|
||||
public static double cbrt(double a) {
|
||||
return FdLibm.Cbrt.compute(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the remainder operation on two arguments as prescribed
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
/* cbrt(x)
|
||||
* Return cube root of x
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
static const unsigned
|
||||
#else
|
||||
static unsigned
|
||||
#endif
|
||||
B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
|
||||
B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
|
||||
|
||||
#ifdef __STDC__
|
||||
static const double
|
||||
#else
|
||||
static double
|
||||
#endif
|
||||
C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
|
||||
D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
|
||||
E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
|
||||
F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
|
||||
G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
|
||||
|
||||
#ifdef __STDC__
|
||||
double cbrt(double x)
|
||||
#else
|
||||
double cbrt(x)
|
||||
double x;
|
||||
#endif
|
||||
{
|
||||
int hx;
|
||||
double r,s,t=0.0,w;
|
||||
unsigned sign;
|
||||
|
||||
|
||||
hx = __HI(x); /* high word of x */
|
||||
sign=hx&0x80000000; /* sign= sign(x) */
|
||||
hx ^=sign;
|
||||
if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
|
||||
if((hx|__LO(x))==0)
|
||||
return(x); /* cbrt(0) is itself */
|
||||
|
||||
__HI(x) = hx; /* x <- |x| */
|
||||
/* rough cbrt to 5 bits */
|
||||
if(hx<0x00100000) /* subnormal number */
|
||||
{__HI(t)=0x43500000; /* set t= 2**54 */
|
||||
t*=x; __HI(t)=__HI(t)/3+B2;
|
||||
}
|
||||
else
|
||||
__HI(t)=hx/3+B1;
|
||||
|
||||
|
||||
/* new cbrt to 23 bits, may be implemented in single precision */
|
||||
r=t*t/x;
|
||||
s=C+r*t;
|
||||
t*=G+F/(s+E+D/s);
|
||||
|
||||
/* chopped to 20 bits and make it larger than cbrt(x) */
|
||||
__LO(t)=0; __HI(t)+=0x00000001;
|
||||
|
||||
|
||||
/* one step newton iteration to 53 bits with error less than 0.667 ulps */
|
||||
s=t*t; /* t*t is exact */
|
||||
r=x/s;
|
||||
w=t+t;
|
||||
r=(r-t)/(w+r); /* r-s is exact */
|
||||
t=t+t*r;
|
||||
|
||||
/* retore the sign bit */
|
||||
__HI(t) |= sign;
|
||||
return(t);
|
||||
}
|
||||
@ -88,12 +88,6 @@ Java_java_lang_StrictMath_sqrt(JNIEnv *env, jclass unused, jdouble d)
|
||||
return (jdouble) jsqrt((double)d);
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_cbrt(JNIEnv *env, jclass unused, jdouble d)
|
||||
{
|
||||
return (jdouble) jcbrt((double)d);
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_atan2(JNIEnv *env, jclass unused, jdouble d1, jdouble d2)
|
||||
{
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.*
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @run main CubeRootTests
|
||||
* @bug 4347132 4939441 8078672
|
||||
* @summary Tests for {Math, StrictMath}.cbrt (use -Dseed=X to set PRNG seed)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.*
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @run main HypotTests
|
||||
* @bug 4851638 4939441 8078672
|
||||
* @summary Tests for {Math, StrictMath}.hypot (use -Dseed=X to set PRNG seed)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.*
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @run main IeeeRecommendedTests
|
||||
* @bug 4860891 4826732 4780454 4939441 4826652 8078672
|
||||
* @summary Tests for IEEE 754[R] recommended functions and similar methods (use -Dseed=X to set PRNG seed)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.*
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @run main Log1pTests
|
||||
* @bug 4851638 4939441 8078672
|
||||
* @summary Tests for {Math, StrictMath}.log1p (use -Dseed=X to set PRNG seed)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,11 +23,20 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4347132
|
||||
* @bug 4347132 8136799
|
||||
* @key randomness
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @build Tests
|
||||
* @build FdlibmTranslit
|
||||
* @build CubeRootTests
|
||||
* @run main CubeRootTests
|
||||
* @summary Tests specifically for StrictMath.cbrt
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
|
||||
import jdk.testlibrary.RandomFactory;
|
||||
|
||||
/**
|
||||
* The tests in ../Math/CubeRootTests.java test properties that should
|
||||
* hold for any cube root implementation, including the FDLIBM-based
|
||||
@ -42,6 +51,19 @@
|
||||
public class CubeRootTests {
|
||||
private CubeRootTests(){}
|
||||
|
||||
public static void main(String [] argv) {
|
||||
int failures = 0;
|
||||
|
||||
failures += testCubeRoot();
|
||||
failures += testAgainstTranslit();
|
||||
|
||||
if (failures > 0) {
|
||||
System.err.println("Testing the cube root incurred "
|
||||
+ failures + " failures.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static int testCubeRootCase(double input, double expected) {
|
||||
int failures=0;
|
||||
|
||||
@ -458,16 +480,44 @@ public class CubeRootTests {
|
||||
return failures;
|
||||
}
|
||||
|
||||
// Initialize shared random number generator
|
||||
private static java.util.Random random = RandomFactory.getRandom();
|
||||
|
||||
public static void main(String [] argv) {
|
||||
/**
|
||||
* Test StrictMath.cbrt against transliteration port of cbrt.
|
||||
*/
|
||||
private static int testAgainstTranslit() {
|
||||
int failures = 0;
|
||||
double x;
|
||||
|
||||
failures += testCubeRoot();
|
||||
// Test just above subnormal threshold...
|
||||
x = Double.MIN_NORMAL;
|
||||
failures += testRange(x, Math.ulp(x), 1000);
|
||||
|
||||
if (failures > 0) {
|
||||
System.err.println("Testing the cube root incurred "
|
||||
+ failures + " failures.");
|
||||
throw new RuntimeException();
|
||||
// ... and just below subnormal threshold ...
|
||||
x = Math.nextDown(Double.MIN_NORMAL);
|
||||
failures += testRange(x, -Math.ulp(x), 1000);
|
||||
|
||||
// ... and near zero.
|
||||
failures += testRange(0.0, Double.MIN_VALUE, 1000);
|
||||
|
||||
x = Tests.createRandomDouble(random);
|
||||
|
||||
// Make the increment twice the ulp value in case the random
|
||||
// value is near an exponent threshold. Don't worry about test
|
||||
// elements overflowing to infinity if the starting value is
|
||||
// near Double.MAX_VALUE.
|
||||
failures += testRange(x, 2.0 * Math.ulp(x), 1000);
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int testRange(double start, double increment, int count) {
|
||||
int failures = 0;
|
||||
double x = start;
|
||||
for (int i = 0; i < count; i++, x += increment) {
|
||||
failures += testCubeRootCase(x, FdlibmTranslit.Cbrt.compute(x));
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +72,67 @@ public class FdlibmTranslit {
|
||||
return Hypot.compute(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* cbrt(x)
|
||||
* Return cube root of x
|
||||
*/
|
||||
public static class Cbrt {
|
||||
// unsigned
|
||||
private static final int B1 = 715094163; /* B1 = (682-0.03306235651)*2**20 */
|
||||
private static final int B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
|
||||
|
||||
private static final double C = 5.42857142857142815906e-01; /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
|
||||
private static final double D = -7.05306122448979611050e-01; /* -864/1225 = 0xBFE691DE, 0x2532C834 */
|
||||
private static final double E = 1.41428571428571436819e+00; /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
|
||||
private static final double F = 1.60714285714285720630e+00; /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
|
||||
private static final double G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
|
||||
|
||||
public static strictfp double compute(double x) {
|
||||
int hx;
|
||||
double r, s, t=0.0, w;
|
||||
int sign; // unsigned
|
||||
|
||||
hx = __HI(x); // high word of x
|
||||
sign = hx & 0x80000000; // sign= sign(x)
|
||||
hx ^= sign;
|
||||
if (hx >= 0x7ff00000)
|
||||
return (x+x); // cbrt(NaN,INF) is itself
|
||||
if ((hx | __LO(x)) == 0)
|
||||
return(x); // cbrt(0) is itself
|
||||
|
||||
x = __HI(x, hx); // x <- |x|
|
||||
// rough cbrt to 5 bits
|
||||
if (hx < 0x00100000) { // subnormal number
|
||||
t = __HI(t, 0x43500000); // set t= 2**54
|
||||
t *= x;
|
||||
t = __HI(t, __HI(t)/3+B2);
|
||||
} else {
|
||||
t = __HI(t, hx/3+B1);
|
||||
}
|
||||
|
||||
// new cbrt to 23 bits, may be implemented in single precision
|
||||
r = t * t/x;
|
||||
s = C + r*t;
|
||||
t *= G + F/(s + E + D/s);
|
||||
|
||||
// chopped to 20 bits and make it larger than cbrt(x)
|
||||
t = __LO(t, 0);
|
||||
t = __HI(t, __HI(t)+0x00000001);
|
||||
|
||||
|
||||
// one step newton iteration to 53 bits with error less than 0.667 ulps
|
||||
s = t * t; // t*t is exact
|
||||
r = x / s;
|
||||
w = t + t;
|
||||
r= (r - t)/(w + r); // r-s is exact
|
||||
t= t + t*r;
|
||||
|
||||
// retore the sign bit
|
||||
t = __HI(t, __HI(t) | sign);
|
||||
return(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hypot(x,y)
|
||||
*
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
* @key randomness
|
||||
* @summary Tests for StrictMath.hypot
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.*
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @build Tests
|
||||
* @build FdlibmTranslit
|
||||
* @build HypotTests
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user