Fixes Math.rint.
Also fixes the NaN handling in Assert.java that I discovered
during testing.
Authors: Goktug Gokdogan, Andrei Korzhevskii
Bug: #9156
Bug-Link: https://github.com/gwtproject/gwt/issues/9156
Change-Id: I2effe1c5ace329b2f708c53a1f83a295da4f5709
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 f996964..cb01dc1 100644
--- a/user/super/com/google/gwt/emul/java/lang/Math.java
+++ b/user/super/com/google/gwt/emul/java/lang/Math.java
@@ -269,15 +269,12 @@
return NativeMath.random();
}
- public static double rint(double d) {
- if (Double.isNaN(d)) {
- return d;
- } else if (Double.isInfinite(d)) {
- return d;
- } else if (d == 0.0d) {
- return d;
+ public static double rint(double x) {
+ double mod2 = x % 2;
+ if ((mod2 == -1.5) || (mod2 == 0.5)) {
+ return NativeMath.floor(x);
} else {
- return round(d);
+ return NativeMath.round(x);
}
}
diff --git a/user/super/com/google/gwt/junit/translatable/junit/framework/Assert.java b/user/super/com/google/gwt/junit/translatable/junit/framework/Assert.java
index 94957ca..1d56fa3 100644
--- a/user/super/com/google/gwt/junit/translatable/junit/framework/Assert.java
+++ b/user/super/com/google/gwt/junit/translatable/junit/framework/Assert.java
@@ -84,7 +84,8 @@
@DoNotInline
public static void assertEquals(String str, double obj1, double obj2,
double delta) {
- if (obj1 == obj2) {
+ // Handles special cases like NaN
+ if (Double.compare(obj1, obj2) == 0) {
return;
} else if (Math.abs(obj1 - obj2) <= delta) {
return;
@@ -96,7 +97,8 @@
@DoNotInline
public static void assertEquals(String str, float obj1, float obj2,
float delta) {
- if (obj1 == obj2) {
+ // Handles special cases like NaN
+ if (Float.compare(obj1, obj2) == 0) {
return;
} else if (Math.abs(obj1 - obj2) <= delta) {
return;
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 9b8bb5d..7f63a27 100644
--- a/user/test/com/google/gwt/emultest/java/lang/MathTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/MathTest.java
@@ -16,6 +16,8 @@
package com.google.gwt.emultest.java.lang;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
import java.math.BigInteger;
@@ -159,6 +161,25 @@
}
}
+ public void testFloor() {
+ double v = Math.floor(0.5);
+ assertEquals(0, v, 0);
+ v = Math.floor(Double.POSITIVE_INFINITY);
+ assertEquals(Double.POSITIVE_INFINITY, v, 0);
+ v = Math.floor(Double.NEGATIVE_INFINITY);
+ assertEquals(Double.NEGATIVE_INFINITY, v, 0);
+ v = Math.floor(Double.NaN);
+ assertEquals(Double.NaN, v, 0);
+ }
+
+ @DoNotRunWith(Platform.HtmlUnitBug)
+ public void testFloor_DoubleMaxValue() {
+ double v = Math.floor(Double.MAX_VALUE);
+ assertEquals(Double.MAX_VALUE, v, 0);
+ v = Math.floor(-Double.MAX_VALUE);
+ assertEquals(-Double.MAX_VALUE, v, 0);
+ }
+
public void testFloorDiv() {
assertEquals(0, Math.floorDiv(0, 1));
assertEquals(1, Math.floorDiv(4, 3));
@@ -377,6 +398,83 @@
}
}
+ public void testRound() {
+ long v = Math.round(0.5);
+ assertEquals(1L, v);
+ v = Math.round(Double.POSITIVE_INFINITY);
+ assertEquals(Long.MAX_VALUE, v, 0);
+ v = Math.round(Double.NEGATIVE_INFINITY);
+ assertEquals(Long.MIN_VALUE, v, 0);
+ v = Math.round(Double.NaN);
+ assertEquals(0, v, 0);
+ }
+
+ @DoNotRunWith(Platform.HtmlUnitBug)
+ public void testRound_DoubleMaxValue() {
+ long v = Math.round(Double.MAX_VALUE);
+ assertEquals(Double.MAX_VALUE, v, 0);
+ v = Math.round(-Double.MAX_VALUE);
+ assertEquals(-Double.MAX_VALUE, v, 0);
+ }
+
+ public void testRint() {
+ final double twoTo52 = 1L << 52;
+ // format: value to be round and expected value
+ final double[] testValues = {
+ 0, 0,
+ 0.5, 0,
+ 0.75, 1,
+ 1.5, 2,
+ 1.75, 2,
+ -0, -0,
+ -0.5, -0,
+ -1.25, -1,
+ -1.5, -2,
+ -2.5, -2,
+ twoTo52, twoTo52,
+ twoTo52 - 0.25, twoTo52,
+ twoTo52 + 0.25, twoTo52,
+ twoTo52 + 0.5, twoTo52,
+ twoTo52 - 0.5, twoTo52,
+ twoTo52 + 0.75, twoTo52 + 1,
+ twoTo52 - 0.75, twoTo52 - 1,
+ -twoTo52, -twoTo52,
+ -twoTo52 + 0.25, -twoTo52,
+ -twoTo52 - 0.25, -twoTo52,
+ -twoTo52 + 0.5, -twoTo52,
+ -twoTo52 - 0.5, -twoTo52,
+ -twoTo52 + 0.75, -twoTo52 + 1,
+ -twoTo52 - 0.75, -twoTo52 - 1,
+ Double.MIN_VALUE, 0,
+ Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+ Double.NaN, Double.NaN,
+ };
+ for (int i = 0; i < testValues.length;) {
+ double v = testValues[i++];
+ double expected = testValues[i++];
+ double actual = Math.rint(v);
+ assertEquals("value: " + v + ", expected: " + expected + ", actual: " + actual,
+ expected, actual, 0);
+ }
+ }
+
+ @DoNotRunWith(Platform.HtmlUnitBug)
+ public void testRint_DoubleMaxValue() {
+ // format: value to be round and expected value
+ final double[] testValues = {
+ Double.MAX_VALUE, Double.MAX_VALUE,
+ -Double.MAX_VALUE, -Double.MAX_VALUE,
+ };
+ for (int i = 0; i < testValues.length;) {
+ double v = testValues[i++];
+ double expected = testValues[i++];
+ double actual = Math.rint(v);
+ assertEquals("value: " + v + ", expected: " + expected + ", actual: " + actual,
+ expected, actual, 0);
+ }
+ }
+
public void testSin() {
double v = Math.sin(0.0);
assertEquals(0.0, v, 1e-7);