blob: 1c34ed9ae92dc8ee20d504f6118489ece9b2b5dd [file] [log] [blame]
// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package backport;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.desugar.backports.AbstractBackportTest;
import com.android.tools.r8.utils.AndroidApiLevel;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public final class MathJava21Test extends AbstractBackportTest {
@Parameters(name = "{0}")
public static Iterable<?> data() {
return getTestParameters()
.withDexRuntimes()
.withCfRuntimesStartingFromIncluding(CfVm.JDK21)
.withAllApiLevelsAlsoForCf()
.build();
}
public MathJava21Test(TestParameters parameters) {
super(parameters, Math.class, Main.class);
registerTarget(AndroidApiLevel.V, 92);
}
static final class Main extends MiniAssert {
public static void main(String[] args) {
testClampInt();
testClampLong();
testClampDouble();
testClampFloat();
testCeilDivIntInt();
testCeilDivIntIntExact();
testCeilDivLongLong();
testCeilDivLongLongExact();
testCeilDivLongInt();
testCeilModIntInt();
testCeilModLongLong();
testCeilModLongInt();
testDivideExactInt();
testDivideExactLong();
testFloorDivExactInt();
testFloorDivExactLong();
testUnsignedMultiplyHigh();
}
private static void testClampInt() {
assertEquals(1, Math.clamp(1, 0, 5));
assertEquals(0, Math.clamp(-1, 0, 5));
assertEquals(5, Math.clamp(10, 0, 5));
try {
Math.clamp(1, 10, 5);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampLong() {
assertEquals(1, Math.clamp(1L, 0L, 5L));
assertEquals(0, Math.clamp(-1L, 0L, 5L));
assertEquals(5, Math.clamp(10L, 0L, 5L));
try {
Math.clamp(1L, 10L, 5L);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampDouble() {
assertEquals(1.0, Math.clamp(1.0, 0.0, 5.0));
assertEquals(0.0, Math.clamp(-1.0, 0.0, 5.0));
assertEquals(5.0, Math.clamp(10.0, 0.0, 5.0));
try {
Math.clamp(1.0, 10.0, 5.0);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
// Check for -/+0.0.
assertEquals(0.0, Math.clamp(-0.0, 0.0, 1.0));
assertEquals(0.0, Math.clamp(0.0, -0.0, 1.0));
assertEquals(-0.0, Math.clamp(-0.0, -1.0, 0.0));
assertEquals(-0.0, Math.clamp(0.0, -1.0, -0.0));
// Check for NaN.
assertEquals(Double.NaN, Math.clamp(Double.NaN, 0.0, 1.0));
try {
Math.clamp(1.0, Double.NaN, 5.0);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
try {
Math.clamp(1.0, 10.0, Double.NaN);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampFloat() {
assertEquals(1.0f, Math.clamp(1.0f, 0.0f, 5.0f));
assertEquals(0.0f, Math.clamp(-1.0f, 0.0f, 5.0f));
assertEquals(5.0f, Math.clamp(10.0f, 0.0f, 5.0f));
try {
Math.clamp(1.0f, 10.0f, 5.0f);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
// Check for -/+0.0f.
assertEquals(0.0f, Math.clamp(-0.0f, 0.0f, 1.0f));
assertEquals(0.0f, Math.clamp(0.0f, -0.0f, 1.0f));
assertEquals(-0.0f, Math.clamp(-0.0f, -1.0f, 0.0f));
assertEquals(-0.0f, Math.clamp(0.0f, -1.0f, -0.0f));
// Check for NaN.
assertEquals(Float.NaN, Math.clamp(Float.NaN, 0.0f, 1.0f));
try {
Math.clamp(1.0f, Float.NaN, 5.0f);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
try {
Math.clamp(1.0f, 10.0f, Float.NaN);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testCeilDivIntInt() {
assertEquals(1, Math.ceilDiv(7, 7));
assertEquals(-1, Math.ceilDiv(-7, 7));
assertEquals(1, Math.ceilDiv(3, 7));
assertEquals(0, Math.ceilDiv(-3, 7));
assertEquals(-2147483648, Math.ceilDiv(Integer.MIN_VALUE, -1));
}
private static void testCeilDivIntIntExact() {
assertEquals(1, Math.ceilDivExact(7, 7));
assertEquals(-1, Math.ceilDivExact(-7, 7));
assertEquals(1, Math.ceilDivExact(3, 7));
assertEquals(0, Math.ceilDivExact(-3, 7));
try {
Math.ceilDivExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testCeilDivLongLong() {
assertEquals(1L, Math.ceilDiv(7L, 7L));
assertEquals(-1L, Math.ceilDiv(-7L, 7L));
assertEquals(1L, Math.ceilDiv(3L, 7L));
assertEquals(0, Math.ceilDiv(-3L, 7L));
assertEquals(-9223372036854775808L, Math.ceilDiv(Long.MIN_VALUE, -1L));
}
private static void testCeilDivLongLongExact() {
assertEquals(1L, Math.ceilDivExact(7L, 7L));
assertEquals(-1L, Math.ceilDivExact(-7L, 7L));
assertEquals(1L, Math.ceilDivExact(3L, 7L));
assertEquals(0, Math.ceilDivExact(-3L, 7L));
try {
Math.ceilDivExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testCeilDivLongInt() {
assertEquals(1L, Math.ceilDiv(7L, 7));
assertEquals(-1L, Math.ceilDiv(-7L, 7));
assertEquals(1L, Math.ceilDiv(3L, 7));
assertEquals(0, Math.ceilDiv(-3L, 7));
assertEquals(-9223372036854775808L, Math.ceilDiv(Long.MIN_VALUE, -1));
}
private static void testCeilModIntInt() {
assertEquals(0, Math.ceilMod(7, 7));
assertEquals(0, Math.ceilMod(-7, 7));
assertEquals(-4, Math.ceilMod(3, 7));
assertEquals(-3, Math.ceilMod(-3, 7));
assertEquals(0, Math.ceilMod(Integer.MIN_VALUE, -1));
}
private static void testCeilModLongLong() {
assertEquals(0L, Math.ceilMod(7L, 7L));
assertEquals(0L, Math.ceilMod(-7L, 7L));
assertEquals(-4L, Math.ceilMod(3L, 7L));
assertEquals(-3L, Math.ceilMod(-3L, 7L));
assertEquals(0L, Math.ceilMod(Long.MIN_VALUE, -1L));
}
private static void testCeilModLongInt() {
assertEquals(0L, Math.ceilMod(7L, 7));
assertEquals(0L, Math.ceilMod(-7L, 7));
assertEquals(-4L, Math.ceilMod(3L, 7));
assertEquals(-3L, Math.ceilMod(-3L, 7));
assertEquals(0L, Math.ceilMod(Long.MIN_VALUE, -1));
}
private static void testDivideExactInt() {
assertEquals(1, Math.divideExact(7, 7));
assertEquals(-1, Math.divideExact(-7, 7));
assertEquals(0, Math.divideExact(3, 7));
assertEquals(0, Math.divideExact(-3, 7));
try {
Math.divideExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testDivideExactLong() {
assertEquals(1L, Math.divideExact(7L, 7L));
assertEquals(-1L, Math.divideExact(-7L, 7L));
assertEquals(0, Math.divideExact(3L, 7L));
assertEquals(0, Math.divideExact(-3L, 7L));
try {
Math.divideExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testFloorDivExactInt() {
assertEquals(1, Math.floorDivExact(7, 7));
assertEquals(-1, Math.floorDivExact(-7, 7));
assertEquals(0, Math.floorDivExact(3, 7));
assertEquals(-1, Math.floorDivExact(-3, 7));
try {
Math.floorDivExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testFloorDivExactLong() {
assertEquals(1L, Math.floorDivExact(7L, 7L));
assertEquals(-1L, Math.floorDivExact(-7L, 7L));
assertEquals(0L, Math.floorDivExact(3L, 7L));
assertEquals(-1L, Math.floorDivExact(-3L, 7L));
try {
Math.floorDivExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testUnsignedMultiplyHigh() {
assertEquals(
31696182030193L, Math.unsignedMultiplyHigh(8222222222222222L, 71111111111111111L));
assertEquals(
71079414929080917L, Math.unsignedMultiplyHigh(-8222222222222222L, 71111111111111111L));
}
}
}