classlib: fix Math exact operations in C and WebAssembly backends

This commit is contained in:
Alexey Andreev 2023-11-19 20:12:44 +01:00
parent 318d4bff93
commit 7108dfbac7
3 changed files with 12 additions and 12 deletions

View File

@ -254,7 +254,7 @@ public final class TMath extends TObject {
return 0;
}
int total = a * b;
if (total / b != a || (a == Integer.MIN_VALUE && b == -1) || (b == Integer.MIN_VALUE && a == -1)) {
if ((a == Integer.MIN_VALUE && b == -1) || (b == Integer.MIN_VALUE && a == -1) || total / b != a) {
throw new ArithmeticException();
}
return total;
@ -273,26 +273,24 @@ public final class TMath extends TObject {
return 0;
}
long total = a * b;
if (total / b != a || (a == Long.MIN_VALUE && b == -1) || (b == Long.MIN_VALUE && a == -1)) {
if ((a == Long.MIN_VALUE && b == -1) || (b == Long.MIN_VALUE && a == -1) || total / b != a) {
throw new ArithmeticException();
}
return total;
}
public static int divideExact(int a, int b) {
int q = a / b;
if ((a & b & q) < 0) { // all 3 are negative
if (a == Integer.MIN_VALUE && b == -1) {
throw new ArithmeticException();
}
return q;
return a / b;
}
public static long divideExact(long a, long b) {
long q = a / b;
if ((a & b & q) < 0) { // all 3 are negative
if (a == Long.MIN_VALUE && b == -1) {
throw new ArithmeticException();
}
return q;
return a / b;
}
@Unmanaged

View File

@ -202,7 +202,6 @@ public class MathTest {
}
@Test
@SkipPlatform({TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.C})
public void exacts() {
try {
Math.incrementExact(Integer.MAX_VALUE);
@ -258,6 +257,12 @@ public class MathTest {
} catch (ArithmeticException e) {
// ok
}
try {
Math.divideExact(Integer.MIN_VALUE, -1);
fail();
} catch (ArithmeticException e) {
// ok
}
IntStream.rangeClosed(-10, 10).forEach(x -> {
assertEquals(x + 1, Math.incrementExact(x));
assertEquals(x - 1, Math.decrementExact(x));

View File

@ -48,9 +48,7 @@ package org.teavm.classlib.java.time;
import static org.testng.Assert.assertEquals;
import org.junit.runner.RunWith;
import org.teavm.junit.SkipPlatform;
import org.teavm.junit.TeaVMTestRunner;
import org.teavm.junit.TestPlatform;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -309,7 +307,6 @@ public class TestDateTimesImplementation {
}
@Test(dataProvider = "safeMultiplyLongLongProviderOverflow", expectedExceptions = ArithmeticException.class)
@SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI})
public void test_safeMultiplyLongLong_overflow(long a, long b) {
Math.multiplyExact(a, b);
}