Fix Math.expm1 implementation
Bug: #9331
Change-Id: I65639c4462155a07333d35d91f2e69f66c62489a
Bug-Link: https://github.com/gwtproject/gwt/issues/9331
diff --git a/user/super/com/google/gwt/emul/java/lang/Math.java b/user/super/com/google/gwt/emul/java/lang/Math.java
index 15bc14c..7d307e5 100644
--- a/user/super/com/google/gwt/emul/java/lang/Math.java
+++ b/user/super/com/google/gwt/emul/java/lang/Math.java
@@ -136,16 +136,7 @@
}
public static double expm1(double d) {
- if (d == 0.0 || Double.isNaN(d)) {
- return d; // "a zero with same sign as argument", arg is zero, so...
- } else if (!Double.isInfinite(d)) {
- if (d < 0.0d) {
- return -1.0d;
- } else {
- return Double.POSITIVE_INFINITY;
- }
- }
- return exp(d) + 1.0d;
+ return d == 0 ? d : exp(d) - 1;
}
public static double floor(double x) {
diff --git a/user/test/com/google/gwt/emultest/java/lang/MathTest.java b/user/test/com/google/gwt/emultest/java/lang/MathTest.java
index ed3ac23..7259c1b 100644
--- a/user/test/com/google/gwt/emultest/java/lang/MathTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/MathTest.java
@@ -42,6 +42,14 @@
assertFalse(isNegativeZero(x));
}
+ private static void assertNaN(double x) {
+ assertTrue(Double.isNaN(x));
+ }
+
+ private static void assertEquals(double expected, double actual) {
+ assertEquals(expected, actual, 0.);
+ }
+
private static boolean isNegativeZero(double x) {
return Double.doubleToLongBits(-0.0) == Double.doubleToLongBits(x);
}
@@ -71,7 +79,7 @@
v = Math.abs(Double.POSITIVE_INFINITY);
assertEquals(Double.POSITIVE_INFINITY, v);
v = Math.abs(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
}
public void testAddExact() {
@@ -156,11 +164,11 @@
v = Math.cos(Math.PI * 1.5);
assertEquals(0.0, v, 1e-7);
v = Math.cos(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.cos(Double.NEGATIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.cos(Double.POSITIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
}
public void testCosh() {
@@ -171,7 +179,7 @@
v = Math.cosh(-1.0);
assertEquals(1.5430806348, v, 1e-7);
v = Math.cosh(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.cosh(Double.NEGATIVE_INFINITY);
assertEquals(Double.POSITIVE_INFINITY, v);
v = Math.cosh(Double.POSITIVE_INFINITY);
@@ -204,6 +212,16 @@
}
}
+ public void testExpm1() {
+ assertNegativeZero(Math.expm1(-0.));
+ assertPositiveZero(Math.expm1(0.));
+ assertNaN(Math.expm1(Double.NaN));
+ assertEquals(Double.POSITIVE_INFINITY, Math.expm1(Double.POSITIVE_INFINITY));
+ assertEquals(-1., Math.expm1(Double.NEGATIVE_INFINITY));
+ assertEquals(-0.632, Math.expm1(-1), 0.001);
+ assertEquals(1.718, Math.expm1(1), 0.001);
+ }
+
public void testFloor() {
double v = Math.floor(0.5);
assertEquals(0, v, 0);
@@ -320,12 +338,12 @@
assertEquals(1d, Math.max(1d, -1d));
assertEquals(-1d, Math.max(-1d, -2d));
assertEquals(-1d, Math.max(-2d, -1d));
- assertTrue(Double.isNaN(Math.max(Double.NaN, 1d)));
- assertTrue(Double.isNaN(Math.max(1d, Double.NaN)));
- assertTrue(Double.isNaN(Math.max(Double.NaN, Double.POSITIVE_INFINITY)));
- assertTrue(Double.isNaN(Math.max(Double.POSITIVE_INFINITY, Double.NaN)));
- assertTrue(Double.isNaN(Math.max(Double.NaN, Double.NEGATIVE_INFINITY)));
- assertTrue(Double.isNaN(Math.max(Double.NEGATIVE_INFINITY, Double.NaN)));
+ assertNaN(Math.max(Double.NaN, 1d));
+ assertNaN(Math.max(1d, Double.NaN));
+ assertNaN(Math.max(Double.NaN, Double.POSITIVE_INFINITY));
+ assertNaN(Math.max(Double.POSITIVE_INFINITY, Double.NaN));
+ assertNaN(Math.max(Double.NaN, Double.NEGATIVE_INFINITY));
+ assertNaN(Math.max(Double.NEGATIVE_INFINITY, Double.NaN));
assertEquals(2f, Math.max(1f, 2f));
assertEquals(2f, Math.max(2f, 1f));
@@ -352,12 +370,12 @@
assertEquals(-1d, Math.min(1d, -1d));
assertEquals(-2d, Math.min(-1d, -2d));
assertEquals(-2d, Math.min(-2d, -1d));
- assertTrue(Double.isNaN(Math.min(Double.NaN, 1d)));
- assertTrue(Double.isNaN(Math.min(1d, Double.NaN)));
- assertTrue(Double.isNaN(Math.min(Double.NaN, Double.POSITIVE_INFINITY)));
- assertTrue(Double.isNaN(Math.min(Double.POSITIVE_INFINITY, Double.NaN)));
- assertTrue(Double.isNaN(Math.min(Double.NaN, Double.NEGATIVE_INFINITY)));
- assertTrue(Double.isNaN(Math.min(Double.NEGATIVE_INFINITY, Double.NaN)));
+ assertNaN(Math.min(Double.NaN, 1d));
+ assertNaN(Math.min(1d, Double.NaN));
+ assertNaN(Math.min(Double.NaN, Double.POSITIVE_INFINITY));
+ assertNaN(Math.min(Double.POSITIVE_INFINITY, Double.NaN));
+ assertNaN(Math.min(Double.NaN, Double.NEGATIVE_INFINITY));
+ assertNaN(Math.min(Double.NEGATIVE_INFINITY, Double.NaN));
assertEquals(1f, Math.min(1f, 2f));
assertEquals(1f, Math.min(2f, 1f));
@@ -519,7 +537,7 @@
}
public void testSignum() {
- assertTrue(Double.isNaN(Math.signum(Double.NaN)));
+ assertNaN(Math.signum(Double.NaN));
assertTrue(isNegativeZero(Math.signum(-0.)));
assertEquals(0., Math.signum(0.), 0);
assertEquals(-1, Math.signum(-2), 0);
@@ -542,11 +560,11 @@
v = Math.sin(Math.PI * 1.5);
assertEquals(-1.0, v, 1e-7);
v = Math.sin(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.sin(Double.NEGATIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.sin(Double.POSITIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
}
public void testSinh() {
@@ -557,7 +575,7 @@
v = Math.sinh(-1.0);
assertEquals(-1.175201193, v, 1e-7);
v = Math.sinh(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.sinh(Double.NEGATIVE_INFINITY);
assertEquals(Double.NEGATIVE_INFINITY, v);
v = Math.sinh(Double.POSITIVE_INFINITY);
@@ -572,11 +590,11 @@
v = Math.tan(-0.0);
assertEquals(-0.0, v, 1e-7);
v = Math.tan(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.tan(Double.NEGATIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.tan(Double.POSITIVE_INFINITY);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
}
public void testTanh() {
@@ -587,7 +605,7 @@
v = Math.tanh(-1.0);
assertEquals(-0.761594155, v, 1e-7);
v = Math.tanh(Double.NaN);
- assertTrue(Double.isNaN(v));
+ assertNaN(v);
v = Math.tanh(Double.NEGATIVE_INFINITY);
assertEquals(-1.0, v, 1e-7);
v = Math.tanh(Double.POSITIVE_INFINITY);