summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NOTICE11
-rw-r--r--expectations/knownfailures.txt17
-rw-r--r--libart/src/main/java/dalvik/system/VMRuntime.java4
-rw-r--r--luni/src/main/java/java/io/ObjectStreamField.java8
-rw-r--r--luni/src/main/java/java/lang/StrictMath.java1552
-rw-r--r--luni/src/main/java/java/util/logging/FileHandler.java14
-rw-r--r--luni/src/main/java/java/util/logging/SocketHandler.java6
-rw-r--r--luni/src/main/java/java/util/logging/XMLFormatter.java66
-rw-r--r--luni/src/main/java/java/util/zip/ZipEntry.java7
-rw-r--r--luni/src/main/native/java_lang_StrictMath.cpp95
-rw-r--r--luni/src/main/native/java_util_jar_StrictJarFile.cpp28
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp3
-rw-r--r--luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java4
13 files changed, 1594 insertions, 221 deletions
diff --git a/NOTICE b/NOTICE
index 951e506..5136b4b 100644
--- a/NOTICE
+++ b/NOTICE
@@ -104,3 +104,14 @@ WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+ =========================================================================
+ == NOTICE file for the fdlibm License. ==
+ =========================================================================
+
+Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+
+Developed at SunSoft, a Sun Microsystems, Inc. business.
+Permission to use, copy, modify, and distribute this
+software is freely granted, provided that this notice
+is preserved.
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 94d0562..fc2ab7e 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1419,11 +1419,20 @@
name: "com.android.org.apache.harmony.logging.tests.java.util.logging.LevelTest#testSerializationCompatibility"
},
{
- description: "java.util.logging: Tests that require java.util.logging code changes to fix.",
- bug: 13882147,
+ description: "java.util.beans: the harmony tests were broken by Android commit 19a270e90b1e992c1f6639f355ae13564c2f3a6a",
+ bug: 17394106,
+ names: [
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerialization",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testGetPropertyChangeListener_String_Normal",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_String_Normal",
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_Normal"
+ ]
+},
+{
+ description: "java.util.beans: the serialized form references org.apache not com.android.org.apache",
+ bug: 17394106,
names: [
- "com.android.org.apache.harmony.logging.tests.java.util.logging.SocketHandlerTest#testConstructor_NoProperties",
- "com.android.org.apache.harmony.logging.tests.java.util.logging.XMLFormatterTest#test_TestFileHandlerClass_constructor"
+ "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerializationCompatibility"
]
},
{
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index a905c71..fca64c7 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -33,6 +33,10 @@ public final class VMRuntime {
*/
private static final VMRuntime THE_ONE = new VMRuntime();
+ // Note: Instruction set names are used to construct the names of some
+ // system properties. To be sure that the properties stay valid the
+ // instruction set name should not exceed 7 characters. See installd
+ // and the package manager for the actual propeties.
private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
= new HashMap<String, String>();
static {
diff --git a/luni/src/main/java/java/io/ObjectStreamField.java b/luni/src/main/java/java/io/ObjectStreamField.java
index 78a6903..2a9b107 100644
--- a/luni/src/main/java/java/io/ObjectStreamField.java
+++ b/luni/src/main/java/java/io/ObjectStreamField.java
@@ -58,13 +58,7 @@ public class ObjectStreamField implements Comparable<Object> {
* if {@code name} or {@code cl} is {@code null}.
*/
public ObjectStreamField(String name, Class<?> cl) {
- if (name == null) {
- throw new NullPointerException("name == null");
- } else if (cl == null) {
- throw new NullPointerException("cl == null");
- }
- this.name = name;
- this.type = new WeakReference<Class<?>>(cl);
+ this(name, cl, false);
}
/**
diff --git a/luni/src/main/java/java/lang/StrictMath.java b/luni/src/main/java/java/lang/StrictMath.java
index f409c06..0cf9883 100644
--- a/luni/src/main/java/java/lang/StrictMath.java
+++ b/luni/src/main/java/java/lang/StrictMath.java
@@ -15,6 +15,19 @@
* limitations under the License.
*/
+/*
+ * acos, asin, atan, cosh, sinh, tanh, exp, expm1, log, log10, log1p, cbrt,
+ * ceil, floor, IEEEremainder, rint, nextafter, and hypot
+ * have been implemented with the following license.
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
package java.lang;
/**
@@ -102,6 +115,21 @@ public final class StrictMath {
return Math.abs(l);
}
+ private static final double PIO2_HI = 1.57079632679489655800e+00;
+ private static final double PIO2_LO = 6.12323399573676603587e-17;
+ private static final double PS0 = 1.66666666666666657415e-01;
+ private static final double PS1 = -3.25565818622400915405e-01;
+ private static final double PS2 = 2.01212532134862925881e-01;
+ private static final double PS3 = -4.00555345006794114027e-02;
+ private static final double PS4 = 7.91534994289814532176e-04;
+ private static final double PS5 = 3.47933107596021167570e-05;
+ private static final double QS1 = -2.40339491173441421878e+00;
+ private static final double QS2 = 2.02094576023350569471e+00;
+ private static final double QS3 = -6.88283971605453293030e-01;
+ private static final double QS4 = 7.70381505559019352791e-02;
+ private static final double HUGE = 1.000e+300;
+ private static final double PIO4_HI = 7.85398163397448278999e-01;
+
/**
* Returns the closest double approximation of the arc cosine of the
* argument within the range {@code [0..pi]}.
@@ -113,11 +141,62 @@ public final class StrictMath {
* <li>{@code acos(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value to compute arc cosine of.
* @return the arc cosine of the argument.
*/
- public static native double acos(double d);
+ public static double acos(double x) {
+ double z, p, q, r, w, s, c, df;
+ int hx, ix;
+ final long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32);
+ ix = hx & 0x7fffffff;
+ if (ix >= 0x3ff00000) { /* |x| >= 1 */
+ if ((((ix - 0x3ff00000) | ((int) bits))) == 0) { /* |x|==1 */
+ if (hx > 0) {
+ return 0.0; /* ieee_acos(1) = 0 */
+ } else {
+ return 3.14159265358979311600e+00 + 2.0 * PIO2_LO; /* ieee_acos(-1)= pi */
+ }
+ }
+ return (x - x) / (x - x); /* ieee_acos(|x|>1) is NaN */
+ }
+
+ if (ix < 0x3fe00000) { /* |x| < 0.5 */
+ if (ix <= 0x3c600000) {
+ return PIO2_HI + PIO2_LO;/* if|x|<2**-57 */
+ }
+
+ z = x * x;
+ p = z * (PS0 + z
+ * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
+ q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
+ r = p / q;
+ return PIO2_HI - (x - (PIO2_LO - x * r));
+ } else if (hx < 0) { /* x < -0.5 */
+ z = (1.00000000000000000000e+00 + x) * 0.5;
+ p = z * (PS0 + z
+ * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
+ q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
+ s = StrictMath.sqrt(z);
+ r = p / q;
+ w = r * s - PIO2_LO;
+ return 3.14159265358979311600e+00 - 2.0 * (s + w);
+ } else { /* x > 0.5 */
+ z = (1.00000000000000000000e+00 - x) * 0.5;
+ s = StrictMath.sqrt(z);
+ df = s;
+ df = Double.longBitsToDouble(
+ Double.doubleToRawLongBits(df) & 0xffffffffL << 32);
+ c = (z - df * df) / (s + df);
+ p = z * (PS0 + z
+ * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
+ q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
+ r = p / q;
+ w = r * s + c;
+ return 2.0 * (df + w);
+ }
+ }
/**
* Returns the closest double approximation of the arc sine of the argument
@@ -130,11 +209,75 @@ public final class StrictMath {
* <li>{@code asin(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose arc sine has to be computed.
* @return the arc sine of the argument.
*/
- public static native double asin(double d);
+ public static double asin(double x) {
+ double t, w, p, q, c, r, s;
+ int hx, ix;
+ final long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32);
+ ix = hx & 0x7fffffff;
+ if (ix >= 0x3ff00000) { /* |x|>= 1 */
+ if ((((ix - 0x3ff00000) | ((int) bits))) == 0) {
+ /* ieee_asin(1)=+-pi/2 with inexact */
+ return x * PIO2_HI + x * PIO2_LO;
+ }
+ return (x - x) / (x - x); /* ieee_asin(|x|>1) is NaN */
+ } else if (ix < 0x3fe00000) { /* |x|<0.5 */
+ if (ix < 0x3e400000) { /* if |x| < 2**-27 */
+ if (HUGE + x > 1.00000000000000000000e+00) {
+ return x;/* return x with inexact if x!=0 */
+ }
+ } else {
+ t = x * x;
+ p = t * (PS0 + t
+ * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5)))));
+ q = 1.00000000000000000000e+00 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4)));
+ w = p / q;
+ return x + x * w;
+ }
+ }
+ /* 1> |x|>= 0.5 */
+ w = 1.00000000000000000000e+00 - Math.abs(x);
+ t = w * 0.5;
+ p = t * (PS0 + t * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5)))));
+ q = 1.00000000000000000000e+00 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4)));
+ s = StrictMath.sqrt(t);
+ if (ix >= 0x3FEF3333) { /* if |x| > 0.975 */
+ w = p / q;
+ t = PIO2_HI - (2.0 * (s + s * w) - PIO2_LO);
+ } else {
+ w = s;
+ w = Double.longBitsToDouble(
+ Double.doubleToRawLongBits(w) & 0xffffffffL << 32);
+ c = (t - w * w) / (s + w);
+ r = p / q;
+ p = 2.0 * s * r - (PIO2_LO - 2.0 * c);
+ q = PIO4_HI - 2.0 * w;
+ t = PIO4_HI - (p - q);
+ }
+ return (hx > 0) ? t : -t;
+ }
+
+ private static final double[] ATANHI = { 4.63647609000806093515e-01,
+ 7.85398163397448278999e-01, 9.82793723247329054082e-01,
+ 1.57079632679489655800e+00 };
+ private static final double[] ATANLO = { 2.26987774529616870924e-17,
+ 3.06161699786838301793e-17, 1.39033110312309984516e-17,
+ 6.12323399573676603587e-17 };
+ private static final double AT0 = 3.33333333333329318027e-01;
+ private static final double AT1 = -1.99999999998764832476e-01;
+ private static final double AT2 = 1.42857142725034663711e-01;
+ private static final double AT3 = -1.11111104054623557880e-01;
+ private static final double AT4 = 9.09088713343650656196e-02;
+ private static final double AT5 = -7.69187620504482999495e-02;
+ private static final double AT6 = 6.66107313738753120669e-02;
+ private static final double AT7= -5.83357013379057348645e-02;
+ private static final double AT8 = 4.97687799461593236017e-02;
+ private static final double AT9 = -3.65315727442169155270e-02;
+ private static final double AT10 = 1.62858201153657823623e-02;
/**
* Returns the closest double approximation of the arc tangent of the
@@ -149,11 +292,73 @@ public final class StrictMath {
* <li>{@code atan(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose arc tangent has to be computed.
* @return the arc tangent of the argument.
*/
- public static native double atan(double d);
+ public static double atan(double x) {
+ double w, s1, s2, z;
+ int ix, hx, id;
+
+ final long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32);
+ ix = hx & 0x7fffffff;
+ if (ix >= 0x44100000) { /* if |x| >= 2^66 */
+ if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (((int) bits) != 0))) {
+ return x + x; /* NaN */
+ }
+ if (hx > 0) {
+ return ATANHI[3] + ATANLO[3];
+ } else {
+ return -ATANHI[3] - ATANLO[3];
+ }
+ }
+ if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
+ if (ix < 0x3e200000) { /* |x| < 2^-29 */
+ if (HUGE + x > 1.00000000000000000000e+00) {
+ return x; /* raise inexact */
+ }
+ }
+ id = -1;
+ } else {
+ x = Math.abs(x);
+ if (ix < 0x3ff30000) { /* |x| < 1.1875 */
+ if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
+ id = 0;
+ x = (2.0 * x - 1.00000000000000000000e+00) / (2.0 + x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1;
+ x = (x - 1.00000000000000000000e+00) / (x + 1.00000000000000000000e+00);
+ }
+ } else {
+ if (ix < 0x40038000) { /* |x| < 2.4375 */
+ id = 2;
+ x = (x - 1.5) / (1.00000000000000000000e+00 + 1.5 * x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3;
+ x = -1.0 / x;
+ }
+ }
+ }
+
+ /* end of argument reduction */
+ z = x * x;
+ w = z * z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z * (AT0 + w * (AT2 + w
+ * (AT4 + w * (AT6 + w * (AT8 + w * AT10)))));
+ s2 = w * (AT1 + w * (AT3 + w * (AT5 + w * (AT7 + w * AT9))));
+ if (id < 0) {
+ return x - x * (s1 + s2);
+ } else {
+ z = ATANHI[id] - ((x * (s1 + s2) - ATANLO[id]) - x);
+ return (hx < 0) ? -z : z;
+ }
+ }
+
+ private static final double PI_O_4 = 7.8539816339744827900E-01;
+ private static final double PI_O_2 = 1.5707963267948965580E+00;
+ private static final double PI_LO = 1.2246467991473531772E-16;
/**
* Returns the closest double approximation of the arc tangent of
@@ -192,7 +397,108 @@ public final class StrictMath {
* the denominator of the value whose atan has to be computed.
* @return the arc tangent of {@code y/x}.
*/
- public static native double atan2(double y, double x);
+ public static double atan2(double y, double x) {
+ double z;
+ int k, m, hx, hy, ix, iy;
+ int lx, ly; // watch out, should be unsigned
+
+ final long yBits = Double.doubleToRawLongBits(y);
+ final long xBits = Double.doubleToRawLongBits(x);
+
+ hx = (int) (xBits >>> 32); // __HI(x);
+ ix = hx & 0x7fffffff;
+ lx = (int) xBits; // __LO(x);
+ hy = (int) (yBits >>> 32); // __HI(y);
+ iy = hy & 0x7fffffff;
+ ly = (int) yBits; // __LO(y);
+ if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000)
+ || ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) { /* x or y is NaN */
+ return x + y;
+ }
+ if ((hx - 0x3ff00000 | lx) == 0) {
+ return StrictMath.atan(y); /* x=1.0 */
+ }
+
+ m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if ((iy | ly) == 0) {
+ switch (m) {
+ case 0:
+ case 1:
+ return y; /* ieee_atan(+-0,+anything)=+-0 */
+ case 2:
+ return 3.14159265358979311600e+00 + TINY;/* ieee_atan(+0,-anything) = pi */
+ case 3:
+ return -3.14159265358979311600e+00 - TINY;/* ieee_atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if ((ix | lx) == 0)
+ return (hy < 0) ? -PI_O_2 - TINY : PI_O_2 + TINY;
+
+ /* when x is INF */
+ if (ix == 0x7ff00000) {
+ if (iy == 0x7ff00000) {
+ switch (m) {
+ case 0:
+ return PI_O_4 + TINY;/* ieee_atan(+INF,+INF) */
+ case 1:
+ return -PI_O_4 - TINY;/* ieee_atan(-INF,+INF) */
+ case 2:
+ return 3.0 * PI_O_4 + TINY;/* ieee_atan(+INF,-INF) */
+ case 3:
+ return -3.0 * PI_O_4 - TINY;/* ieee_atan(-INF,-INF) */
+ }
+ } else {
+ switch (m) {
+ case 0:
+ return 0.0; /* ieee_atan(+...,+INF) */
+ case 1:
+ return -0.0; /* ieee_atan(-...,+INF) */
+ case 2:
+ return 3.14159265358979311600e+00 + TINY; /* ieee_atan(+...,-INF) */
+ case 3:
+ return -3.14159265358979311600e+00 - TINY; /* ieee_atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if (iy == 0x7ff00000)
+ return (hy < 0) ? -PI_O_2 - TINY : PI_O_2 + TINY;
+
+ /* compute y/x */
+ k = (iy - ix) >> 20;
+ if (k > 60) {
+ z = PI_O_2 + 0.5 * PI_LO; /* |y/x| > 2**60 */
+ } else if (hx < 0 && k < -60) {
+ z = 0.0; /* |y|/x < -2**60 */
+ } else {
+ z = StrictMath.atan(Math.abs(y / x)); /* safe to do y/x */
+ }
+
+ switch (m) {
+ case 0:
+ return z; /* ieee_atan(+,+) */
+ case 1:
+ // __HI(z) ^= 0x80000000;
+ z = Double.longBitsToDouble(
+ Double.doubleToRawLongBits(z) ^ (0x80000000L << 32));
+ return z; /* ieee_atan(-,+) */
+ case 2:
+ return 3.14159265358979311600e+00 - (z - PI_LO);/* ieee_atan(+,-) */
+ default: /* case 3 */
+ return (z - PI_LO) - 3.14159265358979311600e+00;/* ieee_atan(-,-) */
+ }
+ }
+
+ private static final int B1 = 715094163;
+ private static final int B2 = 696219795;
+ private static final double C = 5.42857142857142815906e-01;
+ private static final double D = -7.05306122448979611050e-01;
+ private static final double CBRTE = 1.41428571428571436819e+00;
+ private static final double F = 1.60714285714285720630e+00;
+ private static final double G = 3.57142857142857150787e-01;
/**
* Returns the closest double approximation of the cube root of the
@@ -207,11 +513,79 @@ public final class StrictMath {
* <li>{@code cbrt(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose cube root has to be computed.
* @return the cube root of the argument.
*/
- public static native double cbrt(double d);
+ public static double cbrt(double x) {
+ if (x < 0) {
+ return -cbrt(-x);
+ }
+ int hx;
+ double r, s, w;
+ int sign; // caution: should be unsigned
+ long bits = Double.doubleToRawLongBits(x);
+
+ hx = (int) (bits >>> 32);
+ sign = hx & 0x80000000; /* sign= sign(x) */
+ hx ^= sign;
+ if (hx >= 0x7ff00000) {
+ return (x + x); /* ieee_cbrt(NaN,INF) is itself */
+ }
+
+ if ((hx | ((int) bits)) == 0) {
+ return x; /* ieee_cbrt(0) is itself */
+ }
+
+ // __HI(x) = hx; /* x <- |x| */
+ bits &= 0x00000000ffffffffL;
+ bits |= ((long) hx << 32);
+
+ long tBits = Double.doubleToRawLongBits(0.0) & 0x00000000ffffffffL;
+ double t = 0.0;
+ /* rough cbrt to 5 bits */
+ if (hx < 0x00100000) { /* subnormal number */
+ // __HI(t)=0x43500000; /*set t= 2**54*/
+ tBits |= 0x43500000L << 32;
+ t = Double.longBitsToDouble(tBits);
+ t *= x;
+
+ // __HI(t)=__HI(t)/3+B2;
+ tBits = Double.doubleToRawLongBits(t);
+ long tBitsHigh = tBits >> 32;
+ tBits &= 0x00000000ffffffffL;
+ tBits |= ((tBitsHigh / 3) + B2) << 32;
+ t = Double.longBitsToDouble(tBits);
+
+ } else {
+ // __HI(t)=hx/3+B1;
+ tBits |= ((long) ((hx / 3) + B1)) << 32;
+ t = Double.longBitsToDouble(tBits);
+ }
+
+ /* new cbrt to 23 bits, may be implemented in single precision */
+ r = t * t / x;
+ s = C + r * t;
+ t *= G + F / (s + CBRTE + D / s);
+
+ /* chopped to 20 bits and make it larger than ieee_cbrt(x) */
+ tBits = Double.doubleToRawLongBits(t);
+ tBits &= 0xFFFFFFFFL << 32;
+ tBits += 0x00000001L << 32;
+ t = Double.longBitsToDouble(tBits);
+
+ /* 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 */
+ tBits = Double.doubleToRawLongBits(t);
+ tBits |= ((long) sign) << 32;
+ return Double.longBitsToDouble(tBits);
+ }
/**
* Returns the double conversion of the most negative (closest to negative
@@ -227,8 +601,74 @@ public final class StrictMath {
* <li>{@code ceil(NaN) = NaN}</li>
* </ul>
*/
- public static native double ceil(double d);
+ 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;
+ }
+ private static final long ONEBITS = Double.doubleToRawLongBits(1.00000000000000000000e+00)
+ & 0x00000000ffffffffL;
/**
* Returns the closest double approximation of the hyperbolic cosine of the
@@ -241,11 +681,54 @@ public final class StrictMath {
* <li>{@code cosh(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose hyperbolic cosine has to be computed.
* @return the hyperbolic cosine of the argument.
*/
- public static native double cosh(double d);
+ public static double cosh(double x) {
+ double t, w;
+ int ix;
+ final long bits = Double.doubleToRawLongBits(x);
+ ix = (int) (bits >>> 32) & 0x7fffffff;
+
+ /* x is INF or NaN */
+ if (ix >= 0x7ff00000) {
+ return x * x;
+ }
+
+ /* |x| in [0,0.5*ln2], return 1+ieee_expm1(|x|)^2/(2*ieee_exp(|x|)) */
+ if (ix < 0x3fd62e43) {
+ t = expm1(Math.abs(x));
+ w = 1.00000000000000000000e+00 + t;
+ if (ix < 0x3c800000)
+ return w; /* ieee_cosh(tiny) = 1 */
+ return 1.00000000000000000000e+00 + (t * t) / (w + w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (ieee_exp(|x|)+1/ieee_exp(|x|)/2; */
+ if (ix < 0x40360000) {
+ t = exp(Math.abs(x));
+ return 0.5 * t + 0.5 / t;
+ }
+
+ /* |x| in [22, ieee_log(maxdouble)] return half*ieee_exp(|x|) */
+ if (ix < 0x40862E42) {
+ return 0.5 * exp(Math.abs(x));
+ }
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ final long lx = ((ONEBITS >>> 29) + ((int) bits)) & 0x00000000ffffffffL;
+ // watch out: lx should be an unsigned int
+ // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
+ if (ix < 0x408633CE || (ix == 0x408633ce) && (lx <= 0x8fb9f87dL)) {
+ w = exp(0.5 * Math.abs(x));
+ t = 0.5 * w;
+ return t * w;
+ }
+
+ /* |x| > overflowthresold, ieee_cosh(x) overflow */
+ return HUGE * HUGE;
+ }
/**
* Returns the closest double approximation of the cosine of the argument.
@@ -263,6 +746,19 @@ public final class StrictMath {
*/
public static native double cos(double d);
+ private static final double TWON24 = 5.96046447753906250000e-08;
+ private static final double TWO54 = 1.80143985094819840000e+16,
+ TWOM54 = 5.55111512312578270212e-17;
+ private static final double TWOM1000 = 9.33263618503218878990e-302;
+ private static final double O_THRESHOLD = 7.09782712893383973096e+02;
+ private static final double U_THRESHOLD = -7.45133219101941108420e+02;
+ private static final double INVLN2 = 1.44269504088896338700e+00;
+ private static final double P1 = 1.66666666666666019037e-01;
+ private static final double P2 = -2.77777777770155933842e-03;
+ private static final double P3 = 6.61375632143793436117e-05;
+ private static final double P4 = -1.65339022054652515390e-06;
+ private static final double P5 = 4.13813679705723846039e-08;
+
/**
* Returns the closest double approximation of the raising "e" to the power
* of the argument.
@@ -274,11 +770,88 @@ public final class StrictMath {
* <li>{@code exp(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose exponential has to be computed.
* @return the exponential of the argument.
*/
- public static native double exp(double d);
+ public static double exp(double x) {
+ double y, c, t;
+ double hi = 0, lo = 0;
+ int k = 0, xsb;
+ int hx; // should be unsigned, be careful!
+ final long bits = Double.doubleToRawLongBits(x);
+ int lowBits = (int) bits;
+ int highBits = (int) (bits >>> 32);
+ hx = highBits & 0x7fffffff;
+ xsb = (highBits >>> 31) & 1;
+
+ /* filter out non-finite argument */
+ if (hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if (hx >= 0x7ff00000) {
+ if (((hx & 0xfffff) | lowBits) != 0) {
+ return x + x; /* NaN */
+ } else {
+ return (xsb == 0) ? x : 0.0; /* ieee_exp(+-inf)={inf,0} */
+ }
+ }
+
+ if (x > O_THRESHOLD) {
+ return HUGE * HUGE; /* overflow */
+ }
+
+ if (x < U_THRESHOLD) {
+ return TWOM1000 * TWOM1000; /* underflow */
+ }
+ }
+
+ /* argument reduction */
+ if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ hi = x - ((xsb == 0) ? 6.93147180369123816490e-01 :
+ -6.93147180369123816490e-01); // LN2HI[xsb];
+ lo = (xsb == 0) ? 1.90821492927058770002e-10 :
+ -1.90821492927058770002e-10; // LN2LO[xsb];
+ k = 1 - xsb - xsb;
+ } else {
+ k = (int) (INVLN2 * x + ((xsb == 0) ? 0.5 : -0.5 ));//halF[xsb]);
+ t = k;
+ hi = x - t * 6.93147180369123816490e-01; //ln2HI[0]; /* t*ln2HI is exact here */
+ lo = t * 1.90821492927058770002e-10; //ln2LO[0];
+ }
+ x = hi - lo;
+ } else if (hx < 0x3e300000) { /* when |x|<2**-28 */
+ if (HUGE + x > 1.00000000000000000000e+00)
+ return 1.00000000000000000000e+00 + x;/* trigger inexact */
+ } else {
+ k = 0;
+ }
+
+ /* x is now in primary range */
+ t = x * x;
+ c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
+ if (k == 0) {
+ return 1.00000000000000000000e+00 - ((x * c) / (c - 2.0) - x);
+ } else {
+ y = 1.00000000000000000000e+00 - ((lo - (x * c) / (2.0 - c)) - hi);
+ }
+ long yBits = Double.doubleToRawLongBits(y);
+ if (k >= -1021) {
+ yBits += ((long) (k << 20)) << 32; /* add k to y's exponent */
+ return Double.longBitsToDouble(yBits);
+ } else {
+ yBits += ((long) ((k + 1000) << 20)) << 32;/* add k to y's exponent */
+ return Double.longBitsToDouble(yBits) * TWOM1000;
+ }
+ }
+
+ private static final double TINY = 1.0e-300;
+ private static final double LN2_HI = 6.93147180369123816490e-01;
+ private static final double LN2_LO = 1.90821492927058770002e-10;
+ private static final double Q1 = -3.33333333333331316428e-02;
+ private static final double Q2 = 1.58730158725481460165e-03;
+ private static final double Q3 = -7.93650757867487942473e-05;
+ private static final double Q4 = 4.00821782732936239552e-06;
+ private static final double Q5 = -2.01099218183624371326e-07;
/**
* Returns the closest double approximation of <i>{@code e}</i><sup>
@@ -295,17 +868,124 @@ public final class StrictMath {
* <li>{@code expm1(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value to compute the <i>{@code e}</i><sup>{@code d}</sup>
* {@code - 1} of.
- * @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value
- * of the argument.
+ * @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value of the
+ * argument.
*/
- public static native double expm1(double d);
+ public static double expm1(double x) {
+ double y, hi, lo, t, e, hxs, hfx, r1, c = 0.0;
+ int k, xsb;
+ long yBits = 0;
+ final long bits = Double.doubleToRawLongBits(x);
+ int highBits = (int) (bits >>> 32);
+ int lowBits = (int) (bits);
+ int hx = highBits & 0x7fffffff; // caution: should be unsigned!
+ xsb = highBits & 0x80000000; /* sign bit of x */
+ y = xsb == 0 ? x : -x; /* y = |x| */
+
+ /* filter out HUGE and non-finite argument */
+ if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */
+ if (hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if (hx >= 0x7ff00000) {
+ if (((hx & 0xfffff) | lowBits) != 0) {
+ return x + x; /* NaN */
+ } else {
+ return (xsb == 0) ? x : -1.0;/* ieee_exp(+-inf)={inf,-1} */
+ }
+ }
+ if (x > O_THRESHOLD) {
+ return HUGE * HUGE; /* overflow */
+ }
+ }
+ if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */
+ if (x + TINY < 0.0) { /* raise inexact */
+ return TINY - 1.00000000000000000000e+00; /* return -1 */
+ }
+ }
+ }
+ /* argument reduction */
+ if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ if (xsb == 0) {
+ hi = x - LN2_HI;
+ lo = LN2_LO;
+ k = 1;
+ } else {
+ hi = x + LN2_HI;
+ lo = -LN2_LO;
+ k = -1;
+ }
+ } else {
+ k = (int) (INVLN2 * x + ((xsb == 0) ? 0.5 : -0.5));
+ t = k;
+ hi = x - t * LN2_HI; /* t*ln2_hi is exact here */
+ lo = t * LN2_LO;
+ }
+ x = hi - lo;
+ c = (hi - x) - lo;
+ } else if (hx < 0x3c900000) { /* when |x|<2**-54, return x */
+ // t = huge+x; /* return x with inexact flags when x!=0 */
+ // return x - (t-(huge+x));
+ return x; // inexact flag is not set, but Java ignors this flag
+ // anyway
+ } else {
+ k = 0;
+ }
+
+ /* x is now in primary range */
+ hfx = 0.5 * x;
+ hxs = x * hfx;
+ r1 = 1.00000000000000000000e+00 + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
+ t = 3.0 - r1 * hfx;
+ e = hxs * ((r1 - t) / (6.0 - x * t));
+ if (k == 0) {
+ return x - (x * e - hxs); /* c is 0 */
+ } else {
+ e = (x * (e - c) - c);
+ e -= hxs;
+ if (k == -1) {
+ return 0.5 * (x - e) - 0.5;
+ }
+
+ if (k == 1) {
+ if (x < -0.25) {
+ return -2.0 * (e - (x + 0.5));
+ } else {
+ return 1.00000000000000000000e+00 + 2.0 * (x - e);
+ }
+ }
+
+ if (k <= -2 || k > 56) { /* suffice to return ieee_exp(x)-1 */
+ y = 1.00000000000000000000e+00 - (e - x);
+ yBits = Double.doubleToRawLongBits(y);
+ yBits += (((long) k) << 52); /* add k to y's exponent */
+ return Double.longBitsToDouble(yBits) - 1.00000000000000000000e+00;
+ }
+
+ long tBits = Double.doubleToRawLongBits(1.00000000000000000000e+00) & 0x00000000ffffffffL;
+
+ if (k < 20) {
+ tBits |= (((long) 0x3ff00000) - (0x200000 >> k)) << 32;
+ y = Double.longBitsToDouble(tBits) - (e - x);
+ yBits = Double.doubleToRawLongBits(y);
+ yBits += (((long) k) << 52); /* add k to y's exponent */
+ return Double.longBitsToDouble(yBits);
+ } else {
+ tBits |= ((((long) 0x3ff) - k) << 52); /* 2^-k */
+ y = x - (e + Double.longBitsToDouble(tBits));
+ y += 1.00000000000000000000e+00;
+ yBits = Double.doubleToRawLongBits(y);
+ yBits += (((long) k) << 52); /* add k to y's exponent */
+ return Double.longBitsToDouble(yBits);
+ }
+ }
+ }
/**
- * Returns the double conversion of the most positive (closest to
- * positive infinity) integer less than or equal to the argument.
+ * Returns the double conversion of the most positive (closest to positive
+ * infinity) integer less than or equal to the argument.
* <p>
* Special cases:
* <ul>
@@ -316,12 +996,77 @@ public final class StrictMath {
* <li>{@code floor(NaN) = NaN}</li>
* </ul>
*/
- public static native double floor(double d);
+ 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;
+ }
/**
- * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +}
- * <i> {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is
- * without medium underflow or overflow.
+ * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
+ * {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is without
+ * medium underflow or overflow.
* <p>
* Special cases:
* <ul>
@@ -340,7 +1085,134 @@ public final class StrictMath {
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )} value of the
* arguments.
*/
- public static native double hypot(double x, double y);
+ 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;
+ }
+ }
/**
* Returns the remainder of dividing {@code x} by {@code y} using the IEEE
@@ -367,7 +1239,80 @@ public final class StrictMath {
* the denominator of the operation.
* @return the IEEE754 floating point reminder of of {@code x/y}.
*/
- public static native double IEEEremainder(double x, double 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;
+ }
+
+ private static final double LG1 = 6.666666666666735130e-01;
+ private static final double LG2 = 3.999999999940941908e-01;
+ private static final double LG3 = 2.857142874366239149e-01;
+ private static final double LG4 = 2.222219843214978396e-01;
+ private static final double LG5 = 1.818357216161805012e-01;
+ private static final double LG6 = 1.531383769920937332e-01;
+ private static final double LG7 = 1.479819860511658591e-01;
/**
* Returns the closest double approximation of the natural logarithm of the
@@ -383,11 +1328,95 @@ public final class StrictMath {
* <li>{@code log(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose log has to be computed.
* @return the natural logarithm of the argument.
*/
- public static native double log(double d);
+ public static double log(double x) {
+ double hfsq, f, s, z, R, w, t1, t2, dk;
+ int hx, i, j, k = 0;
+ int lx; // watch out, should be unsigned
+
+ long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32); /* high word of x */
+ lx = (int) bits; /* low word of x */
+
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx & 0x7fffffff) | lx) == 0) {
+ return -TWO54 / 0.0; /* ieee_log(+-0)=-inf */
+ }
+
+ if (hx < 0) {
+ return (x - x) / 0.0; /* ieee_log(-#) = NaN */
+ }
+
+ k -= 54;
+ x *= TWO54; /* subnormal number, scale up x */
+ bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32); /* high word of x */
+ }
+
+ if (hx >= 0x7ff00000) {
+ return x + x;
+ }
+
+ k += (hx >> 20) - 1023;
+ hx &= 0x000fffff;
+ bits &= 0x00000000ffffffffL;
+ i = (hx + 0x95f64) & 0x100000;
+ bits |= ((long) hx | (i ^ 0x3ff00000)) << 32; /* normalize x or x/2 */
+ x = Double.longBitsToDouble(bits);
+ k += (i >> 20);
+ f = x - 1.0;
+
+ if ((0x000fffff & (2 + hx)) < 3) { /* |f| < 2**-20 */
+ if (f == 0.0) {
+ if (k == 0) {
+ return 0.0;
+ } else {
+ dk = k;
+ }
+ return dk * LN2_HI + dk * LN2_LO;
+ }
+
+ R = f * f * (0.5 - 0.33333333333333333 * f);
+ if (k == 0) {
+ return f - R;
+ } else {
+ dk = k;
+ return dk * LN2_HI - ((R - dk * LN2_LO) - f);
+ }
+ }
+ s = f / (2.0 + f);
+ dk = k;
+ z = s * s;
+ i = hx - 0x6147a;
+ w = z * z;
+ j = 0x6b851 - hx;
+ t1 = w * (LG2 + w * (LG4 + w * LG6));
+ t2 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
+ i |= j;
+ R = t2 + t1;
+ if (i > 0) {
+ hfsq = 0.5 * f * f;
+ if (k == 0) {
+ return f - (hfsq - s * (hfsq + R));
+ } else {
+ return dk * LN2_HI
+ - ((hfsq - (s * (hfsq + R) + dk * LN2_LO)) - f);
+ }
+ } else {
+ if (k == 0) {
+ return f - s * (f - R);
+ } else {
+ return dk * LN2_HI - ((s * (f - R) - dk * LN2_LO) - f);
+ }
+ }
+ }
+
+ private static final double IVLN10 = 4.34294481903251816668e-01;
+ private static final double LOG10_2HI = 3.01029995663611771306e-01;
+ private static final double LOG10_2LO = 3.69423907715893078616e-13;
/**
* Returns the closest double approximation of the base 10 logarithm of the
@@ -403,11 +1432,54 @@ public final class StrictMath {
* <li>{@code log10(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose base 10 log has to be computed.
- * @return the natural logarithm of the argument.
+ * @return the the base 10 logarithm of x
*/
- public static native double log10(double d);
+ public static double log10(double x) {
+ double y, z;
+ int i, k = 0, hx;
+ int lx; // careful: lx should be unsigned!
+ long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >> 32); /* high word of x */
+ lx = (int) bits; /* low word of x */
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx & 0x7fffffff) | lx) == 0) {
+ return -TWO54 / 0.0; /* ieee_log(+-0)=-inf */
+ }
+
+ if (hx < 0) {
+ return (x - x) / 0.0; /* ieee_log(-#) = NaN */
+ }
+
+ k -= 54;
+ x *= TWO54; /* subnormal number, scale up x */
+ bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >> 32); /* high word of x */
+ }
+
+ if (hx >= 0x7ff00000) {
+ return x + x;
+ }
+
+ k += (hx >> 20) - 1023;
+ i = (int) (((k & 0x00000000ffffffffL) & 0x80000000) >>> 31);
+ hx = (hx & 0x000fffff) | ((0x3ff - i) << 20);
+ y = k + i;
+ bits &= 0x00000000ffffffffL;
+ bits |= ((long) hx) << 32;
+ x = Double.longBitsToDouble(bits); // __HI(x) = hx;
+ z = y * LOG10_2LO + IVLN10 * log(x);
+ return z + y * LOG10_2HI;
+ }
+
+ private static final double LP1 = 6.666666666666735130e-01,
+ LP2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+ LP3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+ LP4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+ LP5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+ LP6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+ LP7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
/**
* Returns the closest double approximation of the natural logarithm of the
@@ -426,11 +1498,107 @@ public final class StrictMath {
* <li>{@code log1p(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value to compute the {@code ln(1+d)} of.
* @return the natural logarithm of the sum of the argument and 1.
*/
- public static native double log1p(double d);
+
+ public static double log1p(double x) {
+ double hfsq, f = 0.0, c = 0.0, s, z, R, u = 0.0;
+ int k, hx, hu = 0, ax;
+
+ final long bits = Double.doubleToRawLongBits(x);
+ hx = (int) (bits >>> 32); /* high word of x */
+ ax = hx & 0x7fffffff;
+
+ k = 1;
+ if (hx < 0x3FDA827A) { /* x < 0.41422 */
+ if (ax >= 0x3ff00000) { /* x <= -1.0 */
+ if (x == -1.0) {
+ return -TWO54 / 0.0; /* ieee_log1p(-1)=+inf */
+ } else {
+ return (x - x) / (x - x); /* ieee_log1p(x<-1)=NaN */
+ }
+ }
+ if (ax < 0x3e200000) {
+ if (TWO54 + x > 0.0 && ax < 0x3c900000) {
+ return x;
+ } else {
+ return x - x * x * 0.5;
+ }
+ }
+ if (hx > 0 || hx <= 0xbfd2bec3) {
+ k = 0;
+ f = x;
+ hu = 1;
+ } /* -0.2929<x<0.41422 */
+ }
+
+ if (hx >= 0x7ff00000) {
+ return x + x;
+ }
+
+ if (k != 0) {
+ long uBits;
+ if (hx < 0x43400000) {
+ u = 1.0 + x;
+ uBits = Double.doubleToRawLongBits(u);
+ hu = (int) (uBits >>> 32);
+ k = (hu >> 20) - 1023;
+ c = (k > 0) ? 1.0 - (u - x) : x - (u - 1.0);/* correction term */
+ c /= u;
+ } else {
+ uBits = Double.doubleToRawLongBits(x);
+ hu = (int) (uBits >>> 32);
+ k = (hu >> 20) - 1023;
+ c = 0;
+ }
+ hu &= 0x000fffff;
+ if (hu < 0x6a09e) {
+ // __HI(u) = hu|0x3ff00000; /* normalize u */
+ uBits &= 0x00000000ffffffffL;
+ uBits |= ((long) hu | 0x3ff00000) << 32;
+ u = Double.longBitsToDouble(uBits);
+ } else {
+ k += 1;
+ // __HI(u) = hu|0x3fe00000; /* normalize u/2 */
+ uBits &= 0xffffffffL;
+ uBits |= ((long) hu | 0x3fe00000) << 32;
+ u = Double.longBitsToDouble(uBits);
+ hu = (0x00100000 - hu) >> 2;
+ }
+ f = u - 1.0;
+ }
+ hfsq = 0.5 * f * f;
+ if (hu == 0) { /* |f| < 2**-20 */
+ if (f == 0.0) {
+ if (k == 0) {
+ return 0.0;
+ } else {
+ c += k * LN2_LO;
+ return k * LN2_HI + c;
+ }
+ }
+
+ R = hfsq * (1.0 - 0.66666666666666666 * f);
+ if (k == 0) {
+ return f - R;
+ } else {
+ return k * LN2_HI - ((R - (k * LN2_LO + c)) - f);
+ }
+ }
+
+ s = f / (2.0 + f);
+ z = s * s;
+ R = z * (LP1 + z * (LP2 + z
+ * (LP3 + z * (LP4 + z * (LP5 + z * (LP6 + z * LP7))))));
+ if (k == 0) {
+ return f - (hfsq - s * (hfsq + R));
+ } else {
+ return k * LN2_HI
+ - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f);
+ }
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
@@ -453,8 +1621,8 @@ public final class StrictMath {
if (d1 != d2)
return Double.NaN;
/* max( +0.0,-0.0) == +0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0)
+ if (d1 == 0.0 &&
+ ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0)
return 0.0;
return d1;
}
@@ -480,8 +1648,8 @@ public final class StrictMath {
if (f1 != f2)
return Float.NaN;
/* max( +0.0,-0.0) == +0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0)
+ if (f1 == 0.0f &&
+ ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0)
return 0.0f;
return f1;
}
@@ -523,8 +1691,8 @@ public final class StrictMath {
if (d1 != d2)
return Double.NaN;
/* min( +0.0,-0.0) == -0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0)
+ if (d1 == 0.0 &&
+ ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0)
return 0.0 * (-1.0);
return d1;
}
@@ -550,8 +1718,8 @@ public final class StrictMath {
if (f1 != f2)
return Float.NaN;
/* min( +0.0,-0.0) == -0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0)
+ if (f1 == 0.0f &&
+ ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0)
return 0.0f * (-1.0f);
return f1;
}
@@ -635,11 +1803,91 @@ public final class StrictMath {
* <li>{@code rint(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value to be rounded.
* @return the closest integer to the argument (as a double).
*/
- public static native double rint(double d);
+ 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;
+ }
+ }
/**
* Returns the result of rounding the argument to an integer. The result is
@@ -706,7 +1954,7 @@ public final class StrictMath {
* the value whose signum has to be computed.
* @return the value of the signum function.
*/
- public static double signum(double d){
+ public static double signum(double d) {
return Math.signum(d);
}
@@ -729,10 +1977,12 @@ public final class StrictMath {
* the value whose signum has to be computed.
* @return the value of the signum function.
*/
- public static float signum(float f){
+ public static float signum(float f) {
return Math.signum(f);
}
+ private static final double shuge = 1.0e307;
+
/**
* Returns the closest double approximation of the hyperbolic sine of the
* argument.
@@ -746,11 +1996,57 @@ public final class StrictMath {
* <li>{@code sinh(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose hyperbolic sine has to be computed.
* @return the hyperbolic sine of the argument.
*/
- public static native double sinh(double d);
+ public static double sinh(double x) {
+ double t, w, h;
+ int ix, jx;
+ final long bits = Double.doubleToRawLongBits(x);
+
+ jx = (int) (bits >>> 32);
+ ix = jx & 0x7fffffff;
+
+ /* x is INF or NaN */
+ if (ix >= 0x7ff00000) {
+ return x + x;
+ }
+
+ h = 0.5;
+ if (jx < 0) {
+ h = -h;
+ }
+
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix < 0x3e300000) /* |x|<2**-28 */
+ if (shuge + x > 1.00000000000000000000e+00) {
+ return x;/* ieee_sinh(tiny) = tiny with inexact */
+ }
+ t = expm1(Math.abs(x));
+ if (ix < 0x3ff00000)
+ return h * (2.0 * t - t * t / (t + 1.00000000000000000000e+00));
+ return h * (t + t / (t + 1.00000000000000000000e+00));
+ }
+
+ /* |x| in [22, ieee_log(maxdouble)] return 0.5*ieee_exp(|x|) */
+ if (ix < 0x40862E42) {
+ return h * exp(Math.abs(x));
+ }
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ final long lx = ((ONEBITS >>> 29) + ((int) bits)) & 0x00000000ffffffffL;
+ // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
+ if (ix < 0x408633CE || (ix == 0x408633ce) && (lx <= 0x8fb9f87dL)) {
+ w = exp(0.5 * Math.abs(x));
+ t = h * w;
+ return t * w;
+ }
+
+ /* |x| > overflowthresold, ieee_sinh(x) overflow */
+ return x * shuge;
+ }
/**
* Returns the closest double approximation of the sine of the argument.
@@ -816,11 +2112,47 @@ public final class StrictMath {
* <li>{@code tanh(NaN) = NaN}</li>
* </ul>
*
- * @param d
+ * @param x
* the value whose hyperbolic tangent has to be computed.
* @return the hyperbolic tangent of the argument
*/
- public static native double tanh(double d);
+ public static double tanh(double x) {
+ double t, z;
+ int jx, ix;
+
+ final long bits = Double.doubleToRawLongBits(x);
+ /* High word of |x|. */
+ jx = (int) (bits >>> 32);
+ ix = jx & 0x7fffffff;
+
+ /* x is INF or NaN */
+ if (ix >= 0x7ff00000) {
+ if (jx >= 0) {
+ return 1.00000000000000000000e+00 / x + 1.00000000000000000000e+00; /* ieee_tanh(+-inf)=+-1 */
+ } else {
+ return 1.00000000000000000000e+00 / x - 1.00000000000000000000e+00; /* ieee_tanh(NaN) = NaN */
+ }
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix < 0x3c800000) { /* |x|<2**-55 */
+ return x * (1.00000000000000000000e+00 + x);/* ieee_tanh(small) = small */
+ }
+
+ if (ix >= 0x3ff00000) { /* |x|>=1 */
+ t = Math.expm1(2.0 * Math.abs(x));
+ z = 1.00000000000000000000e+00 - 2.0 / (t + 2.0);
+ } else {
+ t = Math.expm1(-2.0 * Math.abs(x));
+ z = -t / (t + 2.0);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = 1.00000000000000000000e+00 - TINY; /* raised inexact flag */
+ }
+ return (jx >= 0) ? z : -z;
+ }
/**
* Returns the measure in degrees of the supplied radian angle. The result
@@ -917,11 +2249,78 @@ public final class StrictMath {
return Math.ulp(f);
}
- private static native double nextafter(double x, double y);
+ /**
+ * 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;
+ }
/**
* Returns a double with the given magnitude and the sign of {@code sign}.
* If {@code sign} is NaN, the sign of the result is positive.
+ *
* @since 1.6
*/
public static double copySign(double magnitude, double sign) {
@@ -932,13 +2331,15 @@ public final class StrictMath {
// (Tested on a Nexus One.)
long magnitudeBits = Double.doubleToRawLongBits(magnitude);
long signBits = Double.doubleToRawLongBits((sign != sign) ? 1.0 : sign);
- magnitudeBits = (magnitudeBits & ~Double.SIGN_MASK) | (signBits & Double.SIGN_MASK);
+ magnitudeBits = (magnitudeBits & ~Double.SIGN_MASK)
+ | (signBits & Double.SIGN_MASK);
return Double.longBitsToDouble(magnitudeBits);
}
/**
- * Returns a float with the given magnitude and the sign of {@code sign}.
- * If {@code sign} is NaN, the sign of the result is positive.
+ * Returns a float with the given magnitude and the sign of {@code sign}. If
+ * {@code sign} is NaN, the sign of the result is positive.
+ *
* @since 1.6
*/
public static float copySign(float magnitude, float sign) {
@@ -949,12 +2350,14 @@ public final class StrictMath {
// (Tested on a Nexus One.)
int magnitudeBits = Float.floatToRawIntBits(magnitude);
int signBits = Float.floatToRawIntBits((sign != sign) ? 1.0f : sign);
- magnitudeBits = (magnitudeBits & ~Float.SIGN_MASK) | (signBits & Float.SIGN_MASK);
+ magnitudeBits = (magnitudeBits & ~Float.SIGN_MASK)
+ | (signBits & Float.SIGN_MASK);
return Float.intBitsToFloat(magnitudeBits);
}
/**
* Returns the exponent of float {@code f}.
+ *
* @since 1.6
*/
public static int getExponent(float f) {
@@ -963,14 +2366,17 @@ public final class StrictMath {
/**
* Returns the exponent of double {@code d}.
+ *
* @since 1.6
*/
- public static int getExponent(double d){
+ public static int getExponent(double d) {
return Math.getExponent(d);
}
/**
- * Returns the next double after {@code start} in the given {@code direction}.
+ * Returns the next double after {@code start} in the given
+ * {@code direction}.
+ *
* @since 1.6
*/
public static double nextAfter(double start, double direction) {
@@ -981,7 +2387,9 @@ public final class StrictMath {
}
/**
- * Returns the next float after {@code start} in the given {@code direction}.
+ * Returns the next float after {@code start} in the given {@code direction}
+ * .
+ *
* @since 1.6
*/
public static float nextAfter(float start, double direction) {
@@ -990,6 +2398,7 @@ public final class StrictMath {
/**
* Returns the next double larger than {@code d}.
+ *
* @since 1.6
*/
public static double nextUp(double d) {
@@ -998,6 +2407,7 @@ public final class StrictMath {
/**
* Returns the next float larger than {@code f}.
+ *
* @since 1.6
*/
public static float nextUp(float f) {
@@ -1006,6 +2416,7 @@ public final class StrictMath {
/**
* Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded.
+ *
* @since 1.6
*/
public static double scalb(double d, int scaleFactor) {
@@ -1049,12 +2460,10 @@ public final class StrictMath {
} else {
if (Math.abs(d) >= Double.MIN_NORMAL) {
// common situation
- result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS)
- | (bits & Double.MANTISSA_MASK);
+ result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | (bits & Double.MANTISSA_MASK);
} else {
// origin d is sub-normal, change mantissa to normal style
- result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS)
- | ((bits << (subNormalFactor + 1)) & Double.MANTISSA_MASK);
+ result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | ((bits << (subNormalFactor + 1)) & Double.MANTISSA_MASK);
}
}
return Double.longBitsToDouble(result | sign);
@@ -1062,6 +2471,7 @@ public final class StrictMath {
/**
* Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded.
+ *
* @since 1.6
*/
public static float scalb(float d, int scaleFactor) {
@@ -1073,8 +2483,7 @@ public final class StrictMath {
int factor = ((bits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS)
- Float.EXPONENT_BIAS + scaleFactor;
// calculates the factor of sub-normal values
- int subNormalFactor = Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK)
- - Float.EXPONENT_BITS;
+ int subNormalFactor = Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) - Float.EXPONENT_BITS;
if (subNormalFactor < 0) {
// not sub-normal values
subNormalFactor = 0;
@@ -1105,8 +2514,9 @@ public final class StrictMath {
| (bits & Float.MANTISSA_MASK);
} else {
// origin d is sub-normal, change mantissa to normal style
- result = ((factor + Float.EXPONENT_BIAS) << Float.MANTISSA_BITS)
- | ((bits << (subNormalFactor + 1)) & Float.MANTISSA_MASK);
+ result = ((factor + Float.EXPONENT_BIAS)
+ << Float.MANTISSA_BITS) | (
+ (bits << (subNormalFactor + 1)) & Float.MANTISSA_MASK);
}
}
return Float.intBitsToFloat(result | sign);
@@ -1120,10 +2530,10 @@ public final class StrictMath {
}
// change it to positive
int absDigits = -digits;
- if (Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) <= (32 - absDigits)) {
+ if (Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK)
+ <= (32 - absDigits)) {
// some bits will remain after shifting, calculates its carry
- if ((((bits >> (absDigits - 1)) & 0x1) == 0)
- || Integer.numberOfTrailingZeros(bits) == (absDigits - 1)) {
+ if ((((bits >> (absDigits - 1)) & 0x1) == 0) || Integer.numberOfTrailingZeros(bits) == (absDigits - 1)) {
return bits >> absDigits;
}
return ((bits >> absDigits) + 1);
@@ -1139,10 +2549,10 @@ public final class StrictMath {
}
// change it to positive
long absDigits = -digits;
- if (Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK) <= (64 - absDigits)) {
+ if (Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK)
+ <= (64 - absDigits)) {
// some bits will remain after shifting, calculates its carry
- if ((((bits >> (absDigits - 1)) & 0x1) == 0)
- || Long.numberOfTrailingZeros(bits) == (absDigits - 1)) {
+ if ((((bits >> (absDigits - 1)) & 0x1) == 0) || Long.numberOfTrailingZeros(bits) == (absDigits - 1)) {
return bits >> absDigits;
}
return ((bits >> absDigits) + 1);
diff --git a/luni/src/main/java/java/util/logging/FileHandler.java b/luni/src/main/java/java/util/logging/FileHandler.java
index 6ffef87..1fd1dbf 100644
--- a/luni/src/main/java/java/util/logging/FileHandler.java
+++ b/luni/src/main/java/java/util/logging/FileHandler.java
@@ -261,15 +261,15 @@ public class FileHandler extends StreamHandler {
boolean hasUniqueID = false;
boolean hasGeneration = false;
- // TODO privilege code?
+ String homePath = System.getProperty("user.home");
+ if (homePath == null) {
+ throw new NullPointerException("System property \"user.home\" is null");
+ }
+ boolean homePathHasSepEnd = homePath.endsWith(File.separator);
String tempPath = System.getProperty("java.io.tmpdir");
- boolean tempPathHasSepEnd = (tempPath == null ? false : tempPath
- .endsWith(File.separator));
-
- String homePath = System.getProperty("user.home");
- boolean homePathHasSepEnd = (homePath == null ? false : homePath
- .endsWith(File.separator));
+ tempPath = tempPath == null ? homePath : tempPath;
+ boolean tempPathHasSepEnd = tempPath.endsWith(File.separator);
StringBuilder sb = new StringBuilder();
pattern = pattern.replace('/', File.separatorChar);
diff --git a/luni/src/main/java/java/util/logging/SocketHandler.java b/luni/src/main/java/java/util/logging/SocketHandler.java
index 48bfc0e..c6d4be0 100644
--- a/luni/src/main/java/java/util/logging/SocketHandler.java
+++ b/luni/src/main/java/java/util/logging/SocketHandler.java
@@ -106,9 +106,13 @@ public class SocketHandler extends StreamHandler {
throw new IllegalArgumentException("host == null || host.isEmpty()");
}
// check the validity of the port number
- int p = 0;
+ int p;
try {
p = Integer.parsePositiveInt(port);
+ // Must be >= 0 to get this far. 0 is invalid too.
+ if (p == 0) {
+ throw new IllegalArgumentException("Illegal port argument " + port);
+ }
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Illegal port argument " + port);
}
diff --git a/luni/src/main/java/java/util/logging/XMLFormatter.java b/luni/src/main/java/java/util/logging/XMLFormatter.java
index 0d80b3e..3952596 100644
--- a/luni/src/main/java/java/util/logging/XMLFormatter.java
+++ b/luni/src/main/java/java/util/logging/XMLFormatter.java
@@ -17,6 +17,7 @@
package java.util.logging;
+import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.ResourceBundle;
@@ -50,7 +51,7 @@ public class XMLFormatter extends Formatter {
// call a method of LogRecord to ensure not null
long time = r.getMillis();
// format to date
- String date = MessageFormat.format("{0, date} {0, time}", new Object[] { new Date(time) });
+ String date = MessageFormat.format("{0, date} {0, time}", new Date(time));
String nl = System.lineSeparator();
StringBuilder sb = new StringBuilder();
@@ -59,21 +60,21 @@ public class XMLFormatter extends Formatter {
append(sb, 1, "millis", time);
append(sb, 1, "sequence", r.getSequenceNumber());
if (r.getLoggerName() != null) {
- append(sb, 1, "logger", r.getLoggerName());
+ escapeAndAppend(sb, 1, "logger", r.getLoggerName());
}
append(sb, 1, "level", r.getLevel().getName());
if (r.getSourceClassName() != null) {
append(sb, 1, "class", r.getSourceClassName());
}
if (r.getSourceMethodName() != null) {
- append(sb, 1, "method", r.getSourceMethodName());
+ escapeAndAppend(sb, 1, "method", r.getSourceMethodName());
}
append(sb, 1, "thread", r.getThreadID());
formatMessages(r, sb);
Object[] params = r.getParameters();
if (params != null) {
for (Object element : params) {
- append(sb, 1, "param", element);
+ escapeAndAppend(sb, 1, "param", element);
}
}
formatThrowable(r, sb);
@@ -96,14 +97,14 @@ public class XMLFormatter extends Formatter {
if (message == null) {
message = pattern;
- append(sb, 1, "message", message);
+ escapeAndAppend(sb, 1, "message", message);
} else {
- append(sb, 1, "message", message);
- append(sb, 1, "key", pattern);
- append(sb, 1, "catalog", r.getResourceBundleName());
+ escapeAndAppend(sb, 1, "message", message);
+ escapeAndAppend(sb, 1, "key", pattern);
+ escapeAndAppend(sb, 1, "catalog", r.getResourceBundleName());
}
} else if (pattern != null) {
- append(sb, 1, "message", pattern);
+ escapeAndAppend(sb, 1, "message", pattern);
} else {
sb.append(indent).append("<message/>");
}
@@ -114,13 +115,13 @@ public class XMLFormatter extends Formatter {
if ((t = r.getThrown()) != null) {
String nl = System.lineSeparator();
sb.append(indent).append("<exception>").append(nl);
- append(sb, 2, "message", t.toString());
+ escapeAndAppend(sb, 2, "message", t.toString());
// format throwable's stack trace
StackTraceElement[] elements = t.getStackTrace();
for (StackTraceElement e : elements) {
sb.append(indent).append(indent).append("<frame>").append(nl);
append(sb, 3, "class", e.getClassName());
- append(sb, 3, "method", e.getMethodName());
+ escapeAndAppend(sb, 3, "method", e.getMethodName());
append(sb, 3, "line", e.getLineNumber());
sb.append(indent).append(indent).append("</frame>").append(nl);
}
@@ -138,6 +139,49 @@ public class XMLFormatter extends Formatter {
sb.append(System.lineSeparator());
}
+ private static void escapeAndAppend(StringBuilder sb, int indentCount, String tag, Object value) {
+ if (value == null) {
+ append(sb, indentCount, tag, value);
+ } else {
+ for (int i = 0; i < indentCount; ++i) {
+ sb.append(indent);
+ }
+ sb.append("<").append(tag).append(">");
+ try {
+ escapeXml(sb, value.toString());
+ } catch (IOException e) {
+ throw new AssertionError();
+ }
+ sb.append("</").append(tag).append(">");
+ sb.append(System.lineSeparator());
+ }
+ }
+
+ private static void escapeXml(Appendable valueBuilder, String value) throws IOException {
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '\"':
+ valueBuilder.append("&quot;");
+ break;
+ case '>':
+ valueBuilder.append("&gt;");
+ break;
+ case '<':
+ valueBuilder.append("&lt;");
+ break;
+ case '&':
+ valueBuilder.append("&amp;");
+ break;
+ case '\'':
+ valueBuilder.append("&apos;");
+ break;
+ default:
+ valueBuilder.append(c);
+ }
+ }
+ }
+
/**
* Returns the header string for a set of log records formatted as XML
* strings, using the output handler's encoding if it is defined, otherwise
diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java
index 217cc3c..d007b0f 100644
--- a/luni/src/main/java/java/util/zip/ZipEntry.java
+++ b/luni/src/main/java/java/util/zip/ZipEntry.java
@@ -52,7 +52,6 @@ public class ZipEntry implements ZipConstants, Cloneable {
byte[] extra;
- int nameLength = -1;
long localHeaderRelOffset = -1;
long dataOffset = -1;
@@ -69,7 +68,7 @@ public class ZipEntry implements ZipConstants, Cloneable {
ZipEntry(String name, String comment, long crc, long compressedSize,
long size, int compressionMethod, int time, int modDate, byte[] extra,
- int nameLength, long localHeaderRelOffset, long dataOffset) {
+ long localHeaderRelOffset, long dataOffset) {
this.name = name;
this.comment = comment;
this.crc = crc;
@@ -79,7 +78,6 @@ public class ZipEntry implements ZipConstants, Cloneable {
this.time = time;
this.modDate = modDate;
this.extra = extra;
- this.nameLength = nameLength;
this.localHeaderRelOffset = localHeaderRelOffset;
this.dataOffset = dataOffset;
}
@@ -340,7 +338,6 @@ public class ZipEntry implements ZipConstants, Cloneable {
compressionMethod = ze.compressionMethod;
modDate = ze.modDate;
extra = ze.extra;
- nameLength = ze.nameLength;
localHeaderRelOffset = ze.localHeaderRelOffset;
dataOffset = ze.dataOffset;
}
@@ -412,7 +409,7 @@ public class ZipEntry implements ZipConstants, Cloneable {
compressedSize = ((long) it.readInt()) & 0xffffffffL;
size = ((long) it.readInt()) & 0xffffffffL;
- nameLength = it.readShort() & 0xffff;
+ int nameLength = it.readShort() & 0xffff;
int extraLength = it.readShort() & 0xffff;
int commentByteCount = it.readShort() & 0xffff;
diff --git a/luni/src/main/native/java_lang_StrictMath.cpp b/luni/src/main/native/java_lang_StrictMath.cpp
index cfe375e..972e272 100644
--- a/luni/src/main/native/java_lang_StrictMath.cpp
+++ b/luni/src/main/native/java_lang_StrictMath.cpp
@@ -34,115 +34,20 @@ static jdouble StrictMath_tan(JNIEnv*, jclass, jdouble a) {
return ieee_tan(a);
}
-static jdouble StrictMath_asin(JNIEnv*, jclass, jdouble a) {
- return ieee_asin(a);
-}
-
-static jdouble StrictMath_acos(JNIEnv*, jclass, jdouble a) {
- return ieee_acos(a);
-}
-
-static jdouble StrictMath_atan(JNIEnv*, jclass, jdouble a) {
- return ieee_atan(a);
-}
-
-static jdouble StrictMath_exp(JNIEnv*, jclass, jdouble a) {
- return ieee_exp(a);
-}
-
-static jdouble StrictMath_log(JNIEnv*, jclass, jdouble a) {
- return ieee_log(a);
-}
-
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_atan2(JNIEnv*, jclass, jdouble a, jdouble b) {
- return ieee_atan2(a, b);
-}
-
static jdouble StrictMath_pow(JNIEnv*, jclass, jdouble a, jdouble b) {
return ieee_pow(a,b);
}
-static jdouble StrictMath_sinh(JNIEnv*, jclass, jdouble a) {
- return ieee_sinh(a);
-}
-
-static jdouble StrictMath_tanh(JNIEnv*, jclass, jdouble a) {
- return ieee_tanh(a);
-}
-
-static jdouble StrictMath_cosh(JNIEnv*, jclass, jdouble a) {
- return ieee_cosh(a);
-}
-
-static jdouble StrictMath_log10(JNIEnv*, jclass, jdouble a) {
- return ieee_log10(a);
-}
-
-static jdouble StrictMath_cbrt(JNIEnv*, jclass, jdouble a) {
- return ieee_cbrt(a);
-}
-
-static jdouble StrictMath_expm1(JNIEnv*, jclass, jdouble a) {
- return ieee_expm1(a);
-}
-
-static jdouble StrictMath_hypot(JNIEnv*, jclass, jdouble a, jdouble b) {
- return ieee_hypot(a, b);
-}
-
-static jdouble StrictMath_log1p(JNIEnv*, jclass, jdouble a) {
- return ieee_log1p(a);
-}
-
-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, acos, "!(D)D"),
- NATIVE_METHOD(StrictMath, asin, "!(D)D"),
- NATIVE_METHOD(StrictMath, atan, "!(D)D"),
- NATIVE_METHOD(StrictMath, atan2, "!(DD)D"),
- NATIVE_METHOD(StrictMath, cbrt, "!(D)D"),
- NATIVE_METHOD(StrictMath, ceil, "!(D)D"),
NATIVE_METHOD(StrictMath, cos, "!(D)D"),
- NATIVE_METHOD(StrictMath, cosh, "!(D)D"),
- NATIVE_METHOD(StrictMath, exp, "!(D)D"),
- NATIVE_METHOD(StrictMath, expm1, "!(D)D"),
- NATIVE_METHOD(StrictMath, floor, "!(D)D"),
- NATIVE_METHOD(StrictMath, hypot, "!(DD)D"),
- NATIVE_METHOD(StrictMath, log, "!(D)D"),
- NATIVE_METHOD(StrictMath, log10, "!(D)D"),
- NATIVE_METHOD(StrictMath, log1p, "!(D)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, sinh, "!(D)D"),
NATIVE_METHOD(StrictMath, sqrt, "!(D)D"),
NATIVE_METHOD(StrictMath, tan, "!(D)D"),
- NATIVE_METHOD(StrictMath, tanh, "!(D)D"),
};
void register_java_lang_StrictMath(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods, NELEM(gMethods));
diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
index 7611749..b10ec43 100644
--- a/luni/src/main/native/java_util_jar_StrictJarFile.cpp
+++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
@@ -32,11 +32,10 @@ static void throwIoException(JNIEnv* env, const int32_t errorCode) {
jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode));
}
-static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName,
- const uint16_t nameLength) {
+static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) {
ScopedLocalRef<jclass> zipEntryClass(env, env->FindClass("java/util/zip/ZipEntry"));
const jmethodID zipEntryCtor = env->GetMethodID(zipEntryClass.get(), "<init>",
- "(Ljava/lang/String;Ljava/lang/String;JJJIII[BIJJ)V");
+ "(Ljava/lang/String;Ljava/lang/String;JJJIII[BJJ)V");
return env->NewObject(zipEntryClass.get(),
zipEntryCtor,
@@ -49,7 +48,6 @@ static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName
static_cast<jint>(0), // time
static_cast<jint>(0), // modData
NULL, // byte[] extra
- static_cast<jint>(nameLength),
static_cast<jlong>(-1), // local header offset
static_cast<jlong>(entry.offset));
}
@@ -72,25 +70,20 @@ static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileN
class IterationHandle {
public:
- IterationHandle(const char* prefix) :
- cookie_(NULL), prefix_(strdup(prefix)) {
+ IterationHandle() :
+ cookie_(NULL) {
}
void** CookieAddress() {
return &cookie_;
}
- const char* Prefix() const {
- return prefix_;
- }
-
~IterationHandle() {
- free(prefix_);
+ EndIteration(cookie_);
}
private:
void* cookie_;
- char* prefix_;
};
@@ -101,14 +94,15 @@ static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nati
return static_cast<jlong>(-1);
}
- IterationHandle* handle = new IterationHandle(prefixChars.c_str());
+ IterationHandle* handle = new IterationHandle();
int32_t error = 0;
if (prefixChars.size() == 0) {
error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
handle->CookieAddress(), NULL);
} else {
+ ZipEntryName entry_name(prefixChars.c_str());
error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- handle->CookieAddress(), handle->Prefix());
+ handle->CookieAddress(), &entry_name);
}
if (error) {
@@ -135,7 +129,7 @@ static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterati
entryNameCString[entryName.name_length] = '\0';
ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get()));
- return newZipEntry(env, data, entryNameString.get(), entryName.name_length);
+ return newZipEntry(env, data, entryNameString.get());
}
static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
@@ -147,12 +141,12 @@ static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeH
ZipEntry data;
const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- entryNameChars.c_str(), &data);
+ ZipEntryName(entryNameChars.c_str()), &data);
if (error) {
return NULL;
}
- return newZipEntry(env, data, entryName, entryNameChars.size());
+ return newZipEntry(env, data, entryName);
}
static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index e8e8efb..6808dd6 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -873,8 +873,9 @@ static jint Posix_gettid(JNIEnv* env __unused, jobject) {
return 0;
}
return static_cast<jint>(owner);
+#elif defined(__BIONIC__)
+ return gettid();
#else
- // Neither bionic nor glibc exposes gettid(2).
return syscall(__NR_gettid);
#endif
}
diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
index e2f21e8..30185d1 100644
--- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
@@ -17,10 +17,10 @@
package libcore.java.security.cert;
import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import com.android.org.bouncycastle.asn1.x509.X509Extensions;
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
import com.android.org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
-import com.android.org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -571,7 +571,7 @@ public class CertificateFactoryTest extends TestCase {
}
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
- new SubjectKeyIdentifierStructure(keyPair.getPublic()));
+ SubjectKeyIdentifier.getInstance(keyPair.getPublic().getEncoded()));
certGen.addExtension(X509Extensions.BasicConstraints, true, basicConstraints);
X509Certificate cert = certGen.generate(caKey);