Skip to content

Commit 50faa5f

Browse files
committed
Use more native math functions
1 parent c9c62b1 commit 50faa5f

File tree

3 files changed

+67
-40
lines changed
  • user
    • super/com/google/gwt/emul/java/lang
    • test-super/com/google/gwt/emultest/super/com/google/gwt/emultest/java17/lang
    • test/com/google/gwt/emultest/java8/lang

3 files changed

+67
-40
lines changed

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

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ public static long addExact(long x, long y) {
8787
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.atan2")
8888
public static native double atan2(double y, double x);
8989

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

9493
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.ceil")
9594
public static native double ceil(double x);
@@ -109,9 +108,8 @@ public static float copySign(float magnitude, float sign) {
109108
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.cos")
110109
public static native double cos(double x);
111110

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

116114
public static int decrementExact(int x) {
117115
checkCriticalArithmetic(x != Integer.MIN_VALUE);
@@ -191,9 +189,8 @@ public static long incrementExact(long x) {
191189
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.log")
192190
public static native double log(double x);
193191

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

198195
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.log1p")
199196
public static native double log1p(double x);
@@ -224,12 +221,28 @@ public static long min(long x, long y) {
224221
return x < y ? x : y;
225222
}
226223

224+
public static long multiplyFull(int x, int y) {
225+
return (long) x * (long) y;
226+
}
227+
227228
public static int multiplyExact(int x, int y) {
228229
double r = (double) x * (double) y;
229230
checkCriticalArithmetic(isSafeIntegerRange(r));
230231
return (int) r;
231232
}
232233

234+
public static long multiplyExact(long x, int y) {
235+
if (y == -1) {
236+
return negateExact(x);
237+
}
238+
if (y == 0) {
239+
return 0;
240+
}
241+
long r = x * y;
242+
checkCriticalArithmetic(r / y == x);
243+
return r;
244+
}
245+
233246
public static long multiplyExact(long x, long y) {
234247
if (y == -1) {
235248
return negateExact(x);
@@ -311,13 +324,8 @@ public static float scalb(float f, int scaleFactor) {
311324
return (float) scalb((double) f, scaleFactor);
312325
}
313326

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-
}
327+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sign")
328+
public static native double signum(double d);
321329

322330
public static float signum(float f) {
323331
return (float) signum((double) f);
@@ -326,28 +334,17 @@ public static float signum(float f) {
326334
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sin")
327335
public static native double sin(double x);
328336

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

333340
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.sqrt")
334341
public static native double sqrt(double x);
335342

336343
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.tan")
337344
public static native double tan(double x);
338345

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-
}
346+
@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.tanh")
347+
public static native double tanh(double x);
351348

352349
public static double toDegrees(double x) {
353350
return x * PI_UNDER_180;
@@ -438,7 +435,6 @@ private static boolean isSafeIntegerRange(double value) {
438435

439436
@JsType(isNative = true, name = "Math", namespace = JsPackage.GLOBAL)
440437
private static class NativeMath {
441-
public static double LOG10E;
442438
public static native double round(double x);
443439
}
444440
}

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/java8/lang/MathTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,45 @@ public void testMultiplyExactLongs() {
225225
}
226226
}
227227

228+
public void testMultiplyExactLongInt() {
229+
for (long a : ALL_LONG_CANDIDATES) {
230+
for (int b : ALL_INTEGER_CANDIDATES) {
231+
BigInteger expectedResult = BigInteger.valueOf(a).multiply(BigInteger.valueOf(b));
232+
boolean expectedSuccess = fitsInLong(expectedResult);
233+
try {
234+
assertEquals(a * b, Math.multiplyExact(a, b));
235+
assertTrue(expectedSuccess);
236+
} catch (ArithmeticException e) {
237+
assertFalse(expectedSuccess);
238+
}
239+
}
240+
}
241+
}
242+
243+
public void testMultiplyFull() {
244+
assertEquals(1L, Long.MAX_VALUE
245+
- Math.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE) * 2 - 4L * Integer.MAX_VALUE);
246+
assertEquals(-1L, Long.MAX_VALUE
247+
- 2 * Math.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
248+
249+
assertEquals(1L, hideFromCompiler(Long.MAX_VALUE)
250+
- Math.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE) * 2 - 4L * Integer.MAX_VALUE);
251+
assertEquals(-1L, hideFromCompiler(Long.MAX_VALUE)
252+
- 2 * Math.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
253+
}
254+
255+
public void testCbrt() {
256+
assertEquals(-2, Math.cbrt(-8), EPS);
257+
assertEquals(Double.POSITIVE_INFINITY, Math.cbrt(Double.POSITIVE_INFINITY), EPS);
258+
assertEquals(Double.NEGATIVE_INFINITY, Math.cbrt(Double.NEGATIVE_INFINITY), EPS);
259+
260+
assertEquals(-2, Math.cbrt(hideFromCompiler(-8)), EPS);
261+
assertEquals(Double.POSITIVE_INFINITY,
262+
Math.cbrt(hideFromCompiler(Double.POSITIVE_INFINITY)), EPS);
263+
assertEquals(Double.NEGATIVE_INFINITY,
264+
Math.cbrt(hideFromCompiler(Double.NEGATIVE_INFINITY)), EPS);
265+
}
266+
228267
public void testNegateExact() {
229268
for (int a : ALL_INTEGER_CANDIDATES) {
230269
BigInteger expectedResult = BigInteger.valueOf(a).negate();

0 commit comments

Comments
 (0)