summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2014-09-23 10:08:42 -0700
committerElliott Hughes <enh@google.com>2014-09-23 10:08:42 -0700
commit130893bd0f3ca148fea10e09d92f27c98dbbf49d (patch)
treef5ef602d5b4edccb0d9687690c311627c8414eb5
parent6463939a4b18244756fce20db6e861d13138d220 (diff)
downloadlibcore-130893bd0f3ca148fea10e09d92f27c98dbbf49d.zip
libcore-130893bd0f3ca148fea10e09d92f27c98dbbf49d.tar.gz
libcore-130893bd0f3ca148fea10e09d92f27c98dbbf49d.tar.bz2
Revert "Implements some StrictMath functions for improved performance."
This reverts commit 165e2b4075dadb99afc0856ab3c698809a6355a2.
-rw-r--r--luni/src/main/java/java/lang/StrictMath.java484
-rw-r--r--luni/src/main/native/java_lang_StrictMath.cpp30
2 files changed, 38 insertions, 476 deletions
diff --git a/luni/src/main/java/java/lang/StrictMath.java b/luni/src/main/java/java/lang/StrictMath.java
index 0cf9883..ff4cebf 100644
--- a/luni/src/main/java/java/lang/StrictMath.java
+++ b/luni/src/main/java/java/lang/StrictMath.java
@@ -16,8 +16,7 @@
*/
/*
- * acos, asin, atan, cosh, sinh, tanh, exp, expm1, log, log10, log1p, cbrt,
- * ceil, floor, IEEEremainder, rint, nextafter, and hypot
+ * acos, asin, atan, cosh, sinh, tanh, exp, expm1, log, log10, log1p, and cbrt
* have been implemented with the following license.
* ====================================================
* Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
@@ -601,71 +600,7 @@ public final class StrictMath {
* <li>{@code ceil(NaN) = NaN}</li>
* </ul>
*/
- public static double ceil(double x) {
- final long x_asRawLongBits = Double.doubleToRawLongBits(x);
- int i0 = (int) (x_asRawLongBits >>> 32);
- int i1 = (int) x_asRawLongBits;
- final int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
-
- if (j0 < 20) {
- // Case where x is not zero.
- if (j0 < 0) {
- // Case where absolute value of x is less than 1.
- if (HUGE + x > 0.0) {
- if (i0 < 0) {
- i0 = 0x80000000;
- i1 = 0;
- } else if ((i0 | i1) != 0) {
- i0 = 0x3ff00000;
- i1 = 0;
- }
- }
- } else {
- int i = (0x000fffff) >> j0;
- if (((i0 & i) | i1) == 0) {
- return x;
- } else if (HUGE + x > 0.0) {
- if (i0 > 0) {
- i0 += (0x00100000) >> j0;
- }
- i0 &= (~i);
- i1 = 0;
- }
- }
- } else if (j0 > 51) {
- if (j0 == 0x400) {
- return x + x;
- } else {
- return x;
- }
- } else {
- int i = (0xffffffff) >>> (j0 - 20);
- if ((i1 & i) == 0) {
- return x;
- }
- if (HUGE + x > 0.0) {
- if (i0 > 0) {
- if (j0 == 20) {
- i0 += 1;
- } else {
- int j = i1 + (1 << (52 - j0));
- if ((j ^ Integer.MIN_VALUE) < (i1 ^ Integer.MIN_VALUE)) {
- // Carry value over for rounding purposes.
- i0 += 1;
- }
- i1 = j;
- }
- }
- i1 &= (~i);
- }
- }
- x = Double.doubleToRawLongBits(i1);
- long bits = Double.doubleToRawLongBits(x);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) i0) << 32;
- x = Double.longBitsToDouble(bits);
- return x;
- }
+ public static native double ceil(double d);
private static final long ONEBITS = Double.doubleToRawLongBits(1.00000000000000000000e+00)
& 0x00000000ffffffffL;
@@ -885,7 +820,7 @@ public final class StrictMath {
xsb = highBits & 0x80000000; /* sign bit of x */
y = xsb == 0 ? x : -x; /* y = |x| */
- /* filter out HUGE and non-finite argument */
+ /* filter out huge and non-finite argument */
if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */
if (hx >= 0x40862E42) { /* if |x|>=709.78... */
if (hx >= 0x7ff00000) {
@@ -996,72 +931,7 @@ public final class StrictMath {
* <li>{@code floor(NaN) = NaN}</li>
* </ul>
*/
- public static double floor(double x) {
- final long x_asRawLongBits = Double.doubleToRawLongBits(x);
- int i0 = (int) (x_asRawLongBits >>> 32);
- int i1 = (int) x_asRawLongBits;
- int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
-
- if (j0 < 20) {
- // Case where x is not zero.
- if (j0 < 0) {
- // Case where absolute value of x is less than 1.
- if (HUGE + x > 0.0) {
- if (i0 >= 0) {
- i0 = 0;
- i1 = 0;
- } else if (((i0 & 0x7fffffff) | i1) != 0) {
- i0 = 0xbff00000;
- i1 = 0;
- }
- }
- } else {
- int i = (0x000fffff) >> j0;
- if (((i0 & i) | i1) == 0) {
- return x;
- }
- if (HUGE + x > 0.0) {
- if (i0 < 0) {
- i0 += (0x00100000) >> j0;
- }
- i0 &= (~i);
- i1 = 0;
- }
- }
- } else if (j0 > 51) {
- if (j0 == 0x400) {
- return x + x;
- } else {
- return x;
- }
- } else {
- int i = (0xffffffff) >>> (j0 - 20);
- if ((i1 & i) == 0) {
- return x;
- }
- if (HUGE + x > 0.0) {
- if (i0 < 0) {
- if (j0 == 20) {
- i0 += 1;
- } else {
- int j = i1 + (1 << (52 - j0));
- if (j < i1) {
- // Carry value over for rounding purposes.
- i0 += 1;
- }
- i1 = j;
- }
- }
- i1 &= (~i);
- }
- }
- x = Double.doubleToRawLongBits(i1);
- long bits = Double.doubleToRawLongBits(x);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) i0) << 32;
- x = Double.longBitsToDouble(bits);
- return x;
- }
+ public static native double floor(double d);
/**
* Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
@@ -1085,134 +955,7 @@ public final class StrictMath {
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )} value of the
* arguments.
*/
- public static double hypot(double x, double y) {
- double a;
- double b;
- double t1;
- double t2;
- double y1;
- double y2;
- double w;
- int j;
- long bits;
- x = StrictMath.abs(x);
- y = StrictMath.abs(y);
- // Convert x and y to long values for bitwise manipulation.
- long x_asRawLongBits = Double.doubleToRawLongBits(x);
- long y_asRawLongBits = Double.doubleToRawLongBits(y);
- long ha = (x_asRawLongBits >> 32) & 0x7fffffff;
- long hb = (y_asRawLongBits >> 32) & 0x7fffffff;
- // Ensures that a is always the larger value.
- if (hb > ha) {
- a = y;
- b = x;
- j = (int) ha;
- ha = hb;
- hb = j;
- } else {
- a = x;
- b = y;
- }
- // Deals with edge case where x is significantly larger than y.
- if ((ha - hb) > 0x3c00000) {
- if (a + b == Double.NEGATIVE_INFINITY) {
- return Double.POSITIVE_INFINITY;
- } else {
- return a + b;
- }
- }
- int k = 0;
- // Deals with edge cases where numbers are infinite or invalid.
- if (ha > 0x5f300000) {
- if (ha >= 0x7ff00000) {
- w = a + b;
- if (((ha & 0xfffff) | Double.doubleToRawLongBits(a)) == 0) {
- w = a;
- }
- if (((hb ^ 0x7ff00000) | Double.doubleToRawLongBits(b)) == 0) {
- w = b;
- }
- return w;
- }
- // Scale a and b by 2**-600.
- ha -= 0x25800000;
- hb -= 0x25800000;
- k += 600;
- bits = Double.doubleToRawLongBits(a);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) ha) << 32;
- a = Double.longBitsToDouble(bits);
-
- bits = Double.doubleToRawLongBits(b);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) hb) << 32;
- b = Double.longBitsToDouble(bits);
- }
- // Deals with cases where lesser number is abnormally small.
- if (hb < 0x20b00000) {
- if (hb <= 0x000fffff) {
- if ((hb | (Double.doubleToRawLongBits(b))) == 0) {
- return a;
- }
- t1 = 0;
- bits = Double.doubleToRawLongBits(t1);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) 0x7fd00000) << 32;
- t1 = Double.longBitsToDouble(bits);
- b *= t1;
- a *= t1;
- k -= 1022;
- } else {
- ha += 0x25800000;
- hb += 0x25800000;
- k -= 600;
- bits = Double.doubleToRawLongBits(a);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) ha) << 32;
- a = Double.longBitsToDouble(bits);
- bits = Double.doubleToRawLongBits(b);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) hb) << 32;
- b = Double.longBitsToDouble(bits);
- }
- }
- // Deals with cases where both numbers are not overly large or small.
- w = a - b;
- if (w > b) {
- t1 = 0;
- bits = Double.doubleToRawLongBits(t1);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) ha) << 32;
- t1 = Double.longBitsToDouble(bits);
- t2 = a - t1;
- w = StrictMath.sqrt(t1 * t1 - (b * (-b) - t2 * (a + t1)));
- } else {
- a = a + a;
- y1 = 0;
- bits = Double.doubleToRawLongBits(y1);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) hb) << 32;
- y1 = Double.longBitsToDouble(bits);
- y2 = b - y1;
- t1 = 0;
- bits = Double.doubleToRawLongBits(t1);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) ha + 0x00100000) << 32;
- t1 = Double.longBitsToDouble(bits);
- t2 = a - t1;
- w = StrictMath.sqrt(t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b)));
- }
- if (k != 0) {
- t1 = 1.0;
- bits = Double.doubleToRawLongBits(t1);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) (k << 20)) << 32;
- t1 = Double.longBitsToDouble(bits);
- return t1 * w;
- } else {
- return w;
- }
- }
+ public static native double hypot(double x, double y);
/**
* Returns the remainder of dividing {@code x} by {@code y} using the IEEE
@@ -1239,72 +982,7 @@ public final class StrictMath {
* the denominator of the operation.
* @return the IEEE754 floating point reminder of of {@code x/y}.
*/
- public static double IEEEremainder(double x, double y) {
- final double zero = 0.0;
- // Convert x and y to long data types.
- final long x_asRawLongBits = Double.doubleToRawLongBits(x);
- int hx = (int) (x_asRawLongBits >>> 32);
- int lx = (int) x_asRawLongBits;
- final long y_asRawLongBits = Double.doubleToRawLongBits(y);
- int hy = (int) (y_asRawLongBits >>> 32);
- int ly = (int) y_asRawLongBits;
- long sx = hx & 0x80000000;
- hy &= 0x7fffffff;
- hx &= 0x7fffffff;
-
- // Deals with edge cases like y = 0 and x or y is NaN.
- if ((hy | ly) == 0) {
- return (x * y) / (x * y);
- }
- if ((hx >= 0x7ff00000) || ((hy >= 0x7ff00000) && (((hy - 0x7ff00000) | ly) != 0))) {
- return (x * y) / (x * y);
- }
- if (hy <= 0x7fdfffff) {
- x = x % (y + y);
- }
- if (((hx - hy) | (lx - ly)) == 0) {
- return zero * x;
- }
-
- // Ensures positive remainders are returned.
- double x1 = x;
- double y1 = y;
- x = StrictMath.abs(x);
- y = StrictMath.abs(y);
- double z = x;
- if (hy < 0x00200000) {
- if (x + x > y) {
- z -= y;
- if (z + z >= y) {
- z -= y;
- }
- }
- } else {
- double y_half = 0.5 * y;
- if (x > y_half) {
- z -= y;
- if (z >= y_half) {
- z -= y;
- }
- }
- }
-
- long bits = Double.doubleToRawLongBits(z);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) (sx)) << 32;
- z = Double.longBitsToDouble(bits);
-
- if (x < y && x1 < 0) {
- if ((y - x) < x) {
- z *= -1;
- }
- } else if (x >= y && x1 < 0) {
- if ((x - y) > y / 2) {
- z *= -1;
- }
- }
- return z;
- }
+ public static native double IEEEremainder(double x, double y);
private static final double LG1 = 6.666666666666735130e-01;
private static final double LG2 = 3.999999999940941908e-01;
@@ -1807,87 +1485,7 @@ public final class StrictMath {
* the value to be rounded.
* @return the closest integer to the argument (as a double).
*/
- public static double rint(double x) {
- double w;
- double t;
- long bits;
- // Magic numbers from the fdlibm code.
- double m0 = 4.50359962737049600000e+15;
- double m1 = -4.50359962737049600000e+15;
-
- // Converting x to a long type for bitwise operations.
- final long x_asRawLongBits = Double.doubleToRawLongBits(x);
- int i0 = (int) (x_asRawLongBits >>> 32);
- int i1 = (int) x_asRawLongBits;
- int sx = (i0 >> 31) & 1;
- int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
-
- if (j0 < 20) {
- if (j0 < 0) {
- if (((i0 & 0x7fffffff) | i1) == 0) {
- return x;
- }
- i1 |= (i0 & 0x0fffff);
- i0 &= 0xfffe0000;
- i0 |= ((i1 | -i1) >> 12) & 0x80000;
-
- // Convert x to long and replace its upper bits with i0.
- bits = Double.doubleToRawLongBits(x);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) (i0)) << 32;
- x = Double.longBitsToDouble(bits);
-
- if (sx == 0) {
- w = m0 + x;
- t = w - m0;
- } else {
- w = m1 + x;
- t = w - m1;
- }
- i0 = (int) (Double.doubleToRawLongBits(t) >>> 32);
- bits = Double.doubleToRawLongBits(t);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) ((i0 & 0x7fffffff) | (sx << 31))) << 32;
- t = Double.longBitsToDouble(bits);
- return t;
- } else {
- int i = (0x000fffff) >> j0;
- if (((i0 & i) | i1) == 0) {
- return x;
- }
- i >>= 1;
- if (((i0 & i) | i1) != 0) {
- if (j0 == 19) {
- i1 = 0x40000000;
- } else {
- i0 = (i0 & (~i)) | ((0x20000) >> j0);
- }
- }
- }
- } else if (j0 > 51) {
- if (j0 == 0x400) {
- return x + x;
- } else {
- return x;
- }
- } else {
- int i = ((int) (0xffffffff)) >> (j0 - 20);
- if ((i1 & i) == 0) {
- return x;
- }
- i >>= 1;
- if ((i1 & i) != 0) {
- i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20));
- }
- }
- if (sx == 0) {
- w = m0 + x;
- return w - m0;
- } else {
- w = m1 + x;
- return w - m1;
- }
- }
+ public static native double rint(double d);
/**
* Returns the result of rounding the argument to an integer. The result is
@@ -2249,73 +1847,7 @@ public final class StrictMath {
return Math.ulp(f);
}
- /**
- * Returns the next machine floating-point number of x in the direction
- * toward y.
- */
- private static double nextafter(double x, double y) {
- double small = 1.4e-45;
- long bits;
- boolean raise = false;
- boolean lower = false;
- final long x_asRawLongBits = Double.doubleToRawLongBits(x);
- final long y_asRawLongBits = Double.doubleToRawLongBits(y);
- int hx = (int) x_asRawLongBits;
- int lx = ((int) (x_asRawLongBits >>> 32)) & 0x7fffffff;
- int hy = (int) y_asRawLongBits;
- int ly = ((int) (y_asRawLongBits >>> 32)) & 0x7fffffff;
- int ix = hx & 0x7fffffff;
- int iy = hy & 0x7fffffff;
- // Deals with edge cases where x and y are 0, invalid, or equal.
- if (Double.isNaN(x) || Double.isNaN(y)) {
- return Double.NaN;
- }
- if (x == y) {
- return x;
- }
- if ((ix | lx) == 0) {
- return small;
- }
- // Sets boolean to adjust return value depending on the signs of x and y.
- if (x >= 0) {
- if (x > y || ((hx == hy) && (lx > ly))) {
- lower = true;
- } else {
- raise = true;
- }
- } else {
- if (x > y || ((hx == hy) && (lx > ly))) {
- raise = true;
- } else {
- lower = true;
- }
- }
- hy = hx & 0x7ff00000;
- if (hy >= 0x7ff00000) {
- return x + x;
- }
- if (hy < 0x00100000) {
- y = x * x;
- if (y != x) {
- bits = Double.doubleToRawLongBits(y);
- bits &= 0x00000000FFFFFFFF;
- bits |= ((long) (hy)) << 32;
- y = Double.longBitsToDouble(bits);
- return y;
- }
- }
- // Adjust the return value if necessary.
- bits = Double.doubleToRawLongBits(x);
- bits &= 0x00000000FFFFFFFF;
- if (lower) {
- bits -= 1;
- }
- if (raise) {
- bits += 1;
- }
- x = Double.longBitsToDouble(bits);
- return x;
- }
+ private static native double nextafter(double x, double y);
/**
* Returns a double with the given magnitude and the sign of {@code sign}.
diff --git a/luni/src/main/native/java_lang_StrictMath.cpp b/luni/src/main/native/java_lang_StrictMath.cpp
index 972e272..e8c6dfb 100644
--- a/luni/src/main/native/java_lang_StrictMath.cpp
+++ b/luni/src/main/native/java_lang_StrictMath.cpp
@@ -38,13 +38,43 @@ static jdouble StrictMath_sqrt(JNIEnv*, jclass, jdouble a) {
return ieee_sqrt(a);
}
+static jdouble StrictMath_IEEEremainder(JNIEnv*, jclass, jdouble a, jdouble b) {
+ return ieee_remainder(a, b);
+}
+
+static jdouble StrictMath_floor(JNIEnv*, jclass, jdouble a) {
+ return ieee_floor(a);
+}
+
+static jdouble StrictMath_ceil(JNIEnv*, jclass, jdouble a) {
+ return ieee_ceil(a);
+}
+
+static jdouble StrictMath_rint(JNIEnv*, jclass, jdouble a) {
+ return ieee_rint(a);
+}
+
static jdouble StrictMath_pow(JNIEnv*, jclass, jdouble a, jdouble b) {
return ieee_pow(a,b);
}
+static jdouble StrictMath_hypot(JNIEnv*, jclass, jdouble a, jdouble b) {
+ return ieee_hypot(a, b);
+}
+
+static jdouble StrictMath_nextafter(JNIEnv*, jclass, jdouble a, jdouble b) {
+ return ieee_nextafter(a, b);
+}
+
static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(StrictMath, IEEEremainder, "!(DD)D"),
+ NATIVE_METHOD(StrictMath, ceil, "!(D)D"),
NATIVE_METHOD(StrictMath, cos, "!(D)D"),
+ NATIVE_METHOD(StrictMath, floor, "!(D)D"),
+ NATIVE_METHOD(StrictMath, hypot, "!(DD)D"),
+ NATIVE_METHOD(StrictMath, nextafter, "!(DD)D"),
NATIVE_METHOD(StrictMath, pow, "!(DD)D"),
+ NATIVE_METHOD(StrictMath, rint, "!(D)D"),
NATIVE_METHOD(StrictMath, sin, "!(D)D"),
NATIVE_METHOD(StrictMath, sqrt, "!(D)D"),
NATIVE_METHOD(StrictMath, tan, "!(D)D"),