blob: e39d818865f27f3a8f9f5656370ad70785f20c31 [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 StrictMathJava21Test extends AbstractBackportTest {
@Parameters(name = "{0}")
public static Iterable<?> data() {
return getTestParameters()
.withDexRuntimes()
.withCfRuntimesStartingFromIncluding(CfVm.JDK21)
.withAllApiLevelsAlsoForCf()
.build();
}
public StrictMathJava21Test(TestParameters parameters) {
super(parameters, StrictMath.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, StrictMath.clamp(1, 0, 5));
assertEquals(0, StrictMath.clamp(-1, 0, 5));
assertEquals(5, StrictMath.clamp(10, 0, 5));
try {
StrictMath.clamp(1, 10, 5);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampLong() {
assertEquals(1, StrictMath.clamp(1L, 0L, 5L));
assertEquals(0, StrictMath.clamp(-1L, 0L, 5L));
assertEquals(5, StrictMath.clamp(10L, 0L, 5L));
try {
StrictMath.clamp(1L, 10L, 5L);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampDouble() {
assertEquals(1.0, StrictMath.clamp(1.0, 0.0, 5.0));
assertEquals(0.0, StrictMath.clamp(-1.0, 0.0, 5.0));
assertEquals(5.0, StrictMath.clamp(10.0, 0.0, 5.0));
try {
StrictMath.clamp(1.0, 10.0, 5.0);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
// Check for -/+0.0.
assertEquals(0.0, StrictMath.clamp(-0.0, 0.0, 1.0));
assertEquals(0.0, StrictMath.clamp(0.0, -0.0, 1.0));
assertEquals(-0.0, StrictMath.clamp(-0.0, -1.0, 0.0));
assertEquals(-0.0, StrictMath.clamp(0.0, -1.0, -0.0));
// Check for NaN.
assertEquals(Double.NaN, StrictMath.clamp(Double.NaN, 0.0, 1.0));
try {
StrictMath.clamp(1.0, Double.NaN, 5.0);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
try {
StrictMath.clamp(1.0, 10.0, Double.NaN);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testClampFloat() {
assertEquals(1.0f, StrictMath.clamp(1.0f, 0.0f, 5.0f));
assertEquals(0.0f, StrictMath.clamp(-1.0f, 0.0f, 5.0f));
assertEquals(5.0f, StrictMath.clamp(10.0f, 0.0f, 5.0f));
try {
StrictMath.clamp(1.0f, 10.0f, 5.0f);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
// Check for -/+0.0f.
assertEquals(0.0f, StrictMath.clamp(-0.0f, 0.0f, 1.0f));
assertEquals(0.0f, StrictMath.clamp(0.0f, -0.0f, 1.0f));
assertEquals(-0.0f, StrictMath.clamp(-0.0f, -1.0f, 0.0f));
assertEquals(-0.0f, StrictMath.clamp(0.0f, -1.0f, -0.0f));
// Check for NaN.
assertEquals(Float.NaN, StrictMath.clamp(Float.NaN, 0.0f, 1.0f));
try {
StrictMath.clamp(1.0f, Float.NaN, 5.0f);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
try {
StrictMath.clamp(1.0f, 10.0f, Float.NaN);
fail("Should have thrown");
} catch (IllegalArgumentException ignored) {
}
}
private static void testCeilDivIntInt() {
assertEquals(1, StrictMath.ceilDiv(7, 7));
assertEquals(-1, StrictMath.ceilDiv(-7, 7));
assertEquals(1, StrictMath.ceilDiv(3, 7));
assertEquals(0, StrictMath.ceilDiv(-3, 7));
assertEquals(-2147483648, StrictMath.ceilDiv(Integer.MIN_VALUE, -1));
}
private static void testCeilDivIntIntExact() {
assertEquals(1, StrictMath.ceilDivExact(7, 7));
assertEquals(-1, StrictMath.ceilDivExact(-7, 7));
assertEquals(1, StrictMath.ceilDivExact(3, 7));
assertEquals(0, StrictMath.ceilDivExact(-3, 7));
try {
StrictMath.ceilDivExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testCeilDivLongLong() {
assertEquals(1L, StrictMath.ceilDiv(7L, 7L));
assertEquals(-1L, StrictMath.ceilDiv(-7L, 7L));
assertEquals(1L, StrictMath.ceilDiv(3L, 7L));
assertEquals(0, StrictMath.ceilDiv(-3L, 7L));
assertEquals(-9223372036854775808L, StrictMath.ceilDiv(Long.MIN_VALUE, -1L));
}
private static void testCeilDivLongLongExact() {
assertEquals(1L, StrictMath.ceilDivExact(7L, 7L));
assertEquals(-1L, StrictMath.ceilDivExact(-7L, 7L));
assertEquals(1L, StrictMath.ceilDivExact(3L, 7L));
assertEquals(0, StrictMath.ceilDivExact(-3L, 7L));
try {
StrictMath.ceilDivExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testCeilDivLongInt() {
assertEquals(1L, StrictMath.ceilDiv(7L, 7));
assertEquals(-1L, StrictMath.ceilDiv(-7L, 7));
assertEquals(1L, StrictMath.ceilDiv(3L, 7));
assertEquals(0, StrictMath.ceilDiv(-3L, 7));
assertEquals(-9223372036854775808L, StrictMath.ceilDiv(Long.MIN_VALUE, -1));
}
private static void testCeilModIntInt() {
assertEquals(0, StrictMath.ceilMod(7, 7));
assertEquals(0, StrictMath.ceilMod(-7, 7));
assertEquals(-4, StrictMath.ceilMod(3, 7));
assertEquals(-3, StrictMath.ceilMod(-3, 7));
assertEquals(0, StrictMath.ceilMod(Integer.MIN_VALUE, -1));
}
private static void testCeilModLongLong() {
assertEquals(0L, StrictMath.ceilMod(7L, 7L));
assertEquals(0L, StrictMath.ceilMod(-7L, 7L));
assertEquals(-4L, StrictMath.ceilMod(3L, 7L));
assertEquals(-3L, StrictMath.ceilMod(-3L, 7L));
assertEquals(0L, StrictMath.ceilMod(Long.MIN_VALUE, -1L));
}
private static void testCeilModLongInt() {
assertEquals(0L, StrictMath.ceilMod(7L, 7));
assertEquals(0L, StrictMath.ceilMod(-7L, 7));
assertEquals(-4L, StrictMath.ceilMod(3L, 7));
assertEquals(-3L, StrictMath.ceilMod(-3L, 7));
assertEquals(0L, StrictMath.ceilMod(Long.MIN_VALUE, -1));
}
private static void testDivideExactInt() {
assertEquals(1, StrictMath.divideExact(7, 7));
assertEquals(-1, StrictMath.divideExact(-7, 7));
assertEquals(0, StrictMath.divideExact(3, 7));
assertEquals(0, StrictMath.divideExact(-3, 7));
try {
StrictMath.divideExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testDivideExactLong() {
assertEquals(1L, StrictMath.divideExact(7L, 7L));
assertEquals(-1L, StrictMath.divideExact(-7L, 7L));
assertEquals(0, StrictMath.divideExact(3L, 7L));
assertEquals(0, StrictMath.divideExact(-3L, 7L));
try {
StrictMath.divideExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testFloorDivExactInt() {
assertEquals(1, StrictMath.floorDivExact(7, 7));
assertEquals(-1, StrictMath.floorDivExact(-7, 7));
assertEquals(0, StrictMath.floorDivExact(3, 7));
assertEquals(-1, StrictMath.floorDivExact(-3, 7));
try {
StrictMath.floorDivExact(Integer.MIN_VALUE, -1);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testFloorDivExactLong() {
assertEquals(1L, StrictMath.floorDivExact(7L, 7L));
assertEquals(-1L, StrictMath.floorDivExact(-7L, 7L));
assertEquals(0L, StrictMath.floorDivExact(3L, 7L));
assertEquals(-1L, StrictMath.floorDivExact(-3L, 7L));
try {
StrictMath.floorDivExact(Long.MIN_VALUE, -1L);
fail("Should have thrown");
} catch (ArithmeticException ae) {
}
}
private static void testUnsignedMultiplyHigh() {
assertEquals(
31696182030193L, StrictMath.unsignedMultiplyHigh(8222222222222222L, 71111111111111111L));
assertEquals(
71079414929080917L,
StrictMath.unsignedMultiplyHigh(-8222222222222222L, 71111111111111111L));
}
}
}