Skip to content

Commit d42ad28

Browse files
committed
Use more native math functions
1 parent 7ae4492 commit d42ad28

File tree

5 files changed

+197
-81
lines changed

5 files changed

+197
-81
lines changed

user/super/com/google/gwt/emul/java/lang/Math.java

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@
2626
* Math utility methods and constants.
2727
*/
2828
public final class Math {
29-
// The following methods are not implemented because JS doesn't provide the
30-
// necessary pieces:
31-
// public static double ulp (double x)
32-
// public static float ulp (float x)
33-
// public static int getExponent (double d)
34-
// public static int getExponent (float f)
3529

3630
public static final double E = 2.7182818284590452354;
3731
public static final double PI = 3.14159265358979323846;
@@ -87,9 +81,8 @@ public static long addExact(long x, long y) {
8781
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.atan2")
8882
public static native double atan2(double y, double x);
8983

90-
public static double cbrt(double x) {
91-
return x == 0 || !Double.isFinite(x) ? x : pow(x, 1.0 / 3.0);
92-
}
84+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.cbrt")
85+
public static native double cbrt(double x);
9386

9487
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.ceil")
9588
public static native double ceil(double x);
@@ -109,9 +102,8 @@ public static float copySign(float magnitude, float sign) {
109102
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.cos")
110103
public static native double cos(double x);
111104

112-
public static double cosh(double x) {
113-
return (exp(x) + exp(-x)) / 2;
114-
}
105+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.cosh")
106+
public static native double cosh(double x);
115107

116108
public static int decrementExact(int x) {
117109
checkCriticalArithmetic(x != Integer.MIN_VALUE);
@@ -144,6 +136,10 @@ public static long floorDiv(long dividend, long divisor) {
144136
return ((dividend ^ divisor) >= 0 ? dividend / divisor : ((dividend + 1) / divisor) - 1);
145137
}
146138

139+
public static long floorDiv(long dividend, int divisor) {
140+
return floorDiv(dividend, (long) divisor);
141+
}
142+
147143
public static int floorMod(int dividend, int divisor) {
148144
checkCriticalArithmetic(divisor != 0);
149145
return ((dividend % divisor) + divisor) % divisor;
@@ -154,6 +150,10 @@ public static long floorMod(long dividend, long divisor) {
154150
return ((dividend % divisor) + divisor) % divisor;
155151
}
156152

153+
public static long floorMod(long dividend, int divisor) {
154+
return floorMod(dividend, (long) divisor);
155+
}
156+
157157
@SuppressWarnings("CheckStyle.MethodName")
158158
public static double IEEEremainder(double v, double m) {
159159
double ratio = v / m;
@@ -175,6 +175,25 @@ public static int getExponent(float v) {
175175
return ((JsUtils.floatToRawIntBits(v) >> 23) & 255) - Float.MAX_EXPONENT;
176176
}
177177

178+
public static double ulp(double v) {
179+
if (!Double.isFinite(v)) {
180+
return Math.abs(v);
181+
}
182+
int exponent = Math.getExponent(v);
183+
if (exponent == -1023) {
184+
return Double.MIN_VALUE;
185+
}
186+
return Math.pow(2, exponent - 52);
187+
}
188+
189+
public static float ulp(float v) {
190+
int exponent = Math.getExponent(v);
191+
if (exponent == -Float.MAX_EXPONENT) {
192+
return Float.MIN_VALUE;
193+
}
194+
return (float) Math.pow(2, exponent - 23);
195+
}
196+
178197
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.hypot")
179198
public static native double hypot(double x, double y);
180199

@@ -191,9 +210,8 @@ public static long incrementExact(long x) {
191210
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.log")
192211
public static native double log(double x);
193212

194-
public static double log10(double x) {
195-
return log(x) * NativeMath.LOG10E;
196-
}
213+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.log10")
214+
public static native double log10(double x);
197215

198216
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.log1p")
199217
public static native double log1p(double x);
@@ -224,12 +242,28 @@ public static long min(long x, long y) {
224242
return x < y ? x : y;
225243
}
226244

245+
public static long multiplyFull(int x, int y) {
246+
return (long) x * (long) y;
247+
}
248+
227249
public static int multiplyExact(int x, int y) {
228250
double r = (double) x * (double) y;
229251
checkCriticalArithmetic(isSafeIntegerRange(r));
230252
return (int) r;
231253
}
232254

255+
public static long multiplyExact(long x, int y) {
256+
if (y == -1) {
257+
return negateExact(x);
258+
}
259+
if (y == 0) {
260+
return 0;
261+
}
262+
long r = x * y;
263+
checkCriticalArithmetic(r / y == x);
264+
return r;
265+
}
266+
233267
public static long multiplyExact(long x, long y) {
234268
if (y == -1) {
235269
return negateExact(x);
@@ -311,13 +345,8 @@ public static float scalb(float f, int scaleFactor) {
311345
return (float) scalb((double) f, scaleFactor);
312346
}
313347

314-
public static double signum(double d) {
315-
if (d == 0 || Double.isNaN(d)) {
316-
return d;
317-
} else {
318-
return d < 0 ? -1 : 1;
319-
}
320-
}
348+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sign")
349+
public static native double signum(double d);
321350

322351
public static float signum(float f) {
323352
return (float) signum((double) f);
@@ -326,28 +355,17 @@ public static float signum(float f) {
326355
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sin")
327356
public static native double sin(double x);
328357

329-
public static double sinh(double x) {
330-
return x == 0.0 ? x : (exp(x) - exp(-x)) / 2;
331-
}
358+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sinh")
359+
public static native double sinh(double x);
332360

333361
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sqrt")
334362
public static native double sqrt(double x);
335363

336364
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.tan")
337365
public static native double tan(double x);
338366

339-
public static double tanh(double x) {
340-
if (x == 0.0) {
341-
// -0.0 should return -0.0.
342-
return x;
343-
}
344-
345-
double e2x = exp(2 * x);
346-
if (Double.isInfinite(e2x)) {
347-
return 1;
348-
}
349-
return (e2x - 1) / (e2x + 1);
350-
}
367+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.tanh")
368+
public static native double tanh(double x);
351369

352370
public static double toDegrees(double x) {
353371
return x * PI_UNDER_180;
@@ -438,7 +456,6 @@ private static boolean isSafeIntegerRange(double value) {
438456

439457
@JsType(isNative = true, name = "Math", namespace = JsPackage.GLOBAL)
440458
private static class NativeMath {
441-
public static double LOG10E;
442459
public static native double round(double x);
443460
}
444461
}

user/test-super/com/google/gwt/emultest/super/com/google/gwt/emultest/java17/lang/MathTest.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ public void testAbsExactWithFolding() {
4444
assertThrowsArithmetic(() -> Math.absExact(Long.MIN_VALUE));
4545
}
4646

47-
private <T> T hideFromCompiler(T value) {
48-
if (Math.random() < -1) {
49-
// Can never happen, but fools the compiler enough not to optimize this call.
50-
fail();
51-
}
52-
return value;
53-
}
54-
5547
private void assertThrowsArithmetic(Runnable check) {
5648
try {
5749
check.run();

user/test/com/google/gwt/emultest/java/lang/DoubleTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,8 @@ public void testDoubleConstants() {
161161
assertTrue(Double.MIN_VALUE < Double.MAX_VALUE);
162162
assertFalse(Double.NaN == Double.NaN);
163163
assertEquals(64, Double.SIZE);
164-
// jdk1.6 assertEquals(Math.getExponent(Double.MAX_VALUE),
165-
// Double.MAX_EXPONENT);
166-
// jdk1.6 assertEquals(Math.getExponent(Double.MIN_NORMAL),
167-
// Double.MIN_EXPONENT);
164+
assertEquals(Math.getExponent(Double.MAX_VALUE), Double.MAX_EXPONENT);
165+
assertEquals(Math.getExponent(Double.MIN_NORMAL), Double.MIN_EXPONENT);
168166
// issue 8073 - used to fail in prod mode
169167
assertFalse(Double.isInfinite(Double.NaN));
170168
}

0 commit comments

Comments
 (0)