Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 46 additions & 31 deletions android/guava-tests/test/com/google/common/math/IntMathTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package com.google.common.math;

import static com.google.common.math.IntMath.checkedAdd;
import static com.google.common.math.IntMath.checkedMultiply;
import static com.google.common.math.IntMath.checkedSubtract;
import static com.google.common.math.IntMath.sqrt;
import static com.google.common.math.MathTesting.ALL_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
Expand All @@ -26,7 +29,6 @@
import static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
import static com.google.common.math.TestPlatform.intsCanGoOutOfRange;
import static java.lang.Math.min;
import static java.math.BigInteger.valueOf;
import static java.math.RoundingMode.DOWN;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.UNNECESSARY;
Expand All @@ -50,6 +52,7 @@
*/
@GwtCompatible
@NullUnmarked
@SuppressWarnings("IntMathMod") // We are testing IntMathMod against alternatives.
public class IntMathTest extends TestCase {
public void testMaxSignedPowerOfTwo() {
assertTrue(IntMath.isPowerOfTwo(IntMath.MAX_SIGNED_POWER_OF_TWO));
Expand All @@ -61,7 +64,7 @@ public void testMaxSignedPowerOfTwo() {

public void testCeilingPowerOfTwo() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
BigInteger expectedResult = BigIntegerMath.ceilingPowerOfTwo(BigInteger.valueOf(x));
BigInteger expectedResult = BigIntegerMath.ceilingPowerOfTwo(bigInt(x));
if (fitsInInt(expectedResult)) {
assertEquals(expectedResult.intValue(), IntMath.ceilingPowerOfTwo(x));
} else {
Expand All @@ -72,7 +75,7 @@ public void testCeilingPowerOfTwo() {

public void testFloorPowerOfTwo() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
BigInteger expectedResult = BigIntegerMath.floorPowerOfTwo(BigInteger.valueOf(x));
BigInteger expectedResult = BigIntegerMath.floorPowerOfTwo(bigInt(x));
assertEquals(expectedResult.intValue(), IntMath.floorPowerOfTwo(x));
}
}
Expand Down Expand Up @@ -100,9 +103,8 @@ public void testFloorPowerOfTwoZero() {
@GwtIncompatible // BigIntegerMath // TODO(cpovirk): GWT-enable BigIntegerMath
public void testConstantMaxPowerOfSqrt2Unsigned() {
assertEquals(
/* expected= */ BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Integer.SIZE - 1), FLOOR)
.intValue(),
/* actual= */ IntMath.MAX_POWER_OF_SQRT2_UNSIGNED);
BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Integer.SIZE - 1), FLOOR).intValue(),
IntMath.MAX_POWER_OF_SQRT2_UNSIGNED);
}

@GwtIncompatible // pow()
Expand Down Expand Up @@ -149,8 +151,7 @@ public void testConstantsBiggestBinomials() {

@GwtIncompatible // sqrt
public void testPowersSqrtMaxInt() {
assertEquals(
/* expected= */ sqrt(Integer.MAX_VALUE, FLOOR), /* actual= */ IntMath.FLOOR_SQRT_MAX_INT);
assertEquals(sqrt(Integer.MAX_VALUE, FLOOR), IntMath.FLOOR_SQRT_MAX_INT);
}

@AndroidIncompatible // presumably slow
Expand All @@ -170,7 +171,7 @@ public void testLessThanBranchFree() {
public void testIsPowerOfTwo() {
for (int x : ALL_INTEGER_CANDIDATES) {
// Checks for a single bit set.
BigInteger bigX = BigInteger.valueOf(x);
BigInteger bigX = bigInt(x);
boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
assertEquals(expected, IntMath.isPowerOfTwo(x));
}
Expand All @@ -194,7 +195,7 @@ public void testLog2NegativeAlwaysThrows() {
public void testLog2MatchesBigInteger() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
assertEquals(BigIntegerMath.log2(valueOf(x), mode), IntMath.log2(x, mode));
assertEquals(BigIntegerMath.log2(bigInt(x), mode), IntMath.log2(x, mode));
}
}
}
Expand Down Expand Up @@ -235,7 +236,7 @@ public void testLog10MatchesBigInteger() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
// The BigInteger implementation is tested separately, use it as the reference.
assertEquals(BigIntegerMath.log10(valueOf(x), mode), IntMath.log10(x, mode));
assertEquals(BigIntegerMath.log10(bigInt(x), mode), IntMath.log10(x, mode));
}
}
}
Expand Down Expand Up @@ -271,6 +272,7 @@ public void testSqrtZeroAlwaysZero() {
}
}

@SuppressWarnings("EnumValuesLoopToEnumSet") // EnumSet.allOf isn't available under J2KT
@GwtIncompatible // sqrt
public void testSqrtNegativeAlwaysThrows() {
for (int x : NEGATIVE_INTEGER_CANDIDATES) {
Expand All @@ -288,7 +290,7 @@ public void testSqrtMatchesBigInteger() {
// The BigInteger implementation is tested separately, use it as the reference.
// Promote the int value (rather than using intValue() on the expected value) to avoid
// any risk of truncation which could lead to a false positive.
assertEquals(BigIntegerMath.sqrt(valueOf(x), mode), valueOf(sqrt(x, mode)));
assertEquals(BigIntegerMath.sqrt(bigInt(x), mode), bigInt(sqrt(x, mode)));
}
}
}
Expand All @@ -313,7 +315,7 @@ public void testSqrtExactMatchesFloorOrThrows() {
public void testPow() {
for (int i : ALL_INTEGER_CANDIDATES) {
for (int pow : EXPONENTS) {
assertEquals(i + "^" + pow, BigInteger.valueOf(i).pow(pow).intValue(), IntMath.pow(i, pow));
assertEquals(i + "^" + pow, bigInt(i).pow(pow).intValue(), IntMath.pow(i, pow));
}
}
}
Expand All @@ -330,7 +332,7 @@ public void testDivNonZero() {
continue;
}
int expected =
new BigDecimal(valueOf(p)).divide(new BigDecimal(valueOf(q)), 0, mode).intValue();
new BigDecimal(bigInt(p)).divide(new BigDecimal(bigInt(q)), 0, mode).intValue();
assertEquals(p + "/" + q, force32(expected), IntMath.divide(p, q, mode));
// Check the assertions we make in the javadoc.
if (mode == DOWN) {
Expand Down Expand Up @@ -381,7 +383,7 @@ public void testDivByZeroAlwaysFails() {
public void testMod() {
for (int x : ALL_INTEGER_CANDIDATES) {
for (int m : POSITIVE_INTEGER_CANDIDATES) {
assertEquals(valueOf(x).mod(valueOf(m)).intValue(), IntMath.mod(x, m));
assertEquals(bigInt(x).mod(bigInt(m)).intValue(), IntMath.mod(x, m));
}
}
}
Expand All @@ -403,7 +405,7 @@ public void testModZeroModulusFails() {
public void testGCD() {
for (int a : POSITIVE_INTEGER_CANDIDATES) {
for (int b : POSITIVE_INTEGER_CANDIDATES) {
assertEquals(valueOf(a).gcd(valueOf(b)), valueOf(IntMath.gcd(a, b)));
assertEquals(bigInt(a).gcd(bigInt(b)), bigInt(IntMath.gcd(a, b)));
}
}
}
Expand Down Expand Up @@ -431,13 +433,15 @@ public void testGCDNegativeZeroThrows() {
}

@AndroidIncompatible // slow
@SuppressWarnings("InlineMeInliner") // We need to test checkedAdd
public void testCheckedAdd() {
for (int a : ALL_INTEGER_CANDIDATES) {
for (int b : ALL_INTEGER_CANDIDATES) {
BigInteger expectedResult = valueOf(a).add(valueOf(b));
// TODO: cpovirk - Test against Math.addExact instead?
BigInteger expectedResult = bigInt(a).add(bigInt(b));
boolean expectedSuccess = fitsInInt(expectedResult);
try {
assertEquals(a + b, IntMath.checkedAdd(a, b));
assertEquals(a + b, checkedAdd(a, b));
assertTrue(expectedSuccess);
} catch (ArithmeticException e) {
assertFalse(expectedSuccess);
Expand All @@ -446,14 +450,16 @@ public void testCheckedAdd() {
}
}

@SuppressWarnings("InlineMeInliner") // We need to test checkedSubtract
@AndroidIncompatible // slow
public void testCheckedSubtract() {
for (int a : ALL_INTEGER_CANDIDATES) {
for (int b : ALL_INTEGER_CANDIDATES) {
BigInteger expectedResult = valueOf(a).subtract(valueOf(b));
// TODO: cpovirk - Test against Math.subtractExact instead?
BigInteger expectedResult = bigInt(a).subtract(bigInt(b));
boolean expectedSuccess = fitsInInt(expectedResult);
try {
assertEquals(a - b, IntMath.checkedSubtract(a, b));
assertEquals(a - b, checkedSubtract(a, b));
assertTrue(expectedSuccess);
} catch (ArithmeticException e) {
assertFalse(expectedSuccess);
Expand All @@ -462,14 +468,16 @@ public void testCheckedSubtract() {
}
}

@SuppressWarnings("InlineMeInliner") // We need to test checkedMultiply
@AndroidIncompatible // presumably slow
public void testCheckedMultiply() {
for (int a : ALL_INTEGER_CANDIDATES) {
for (int b : ALL_INTEGER_CANDIDATES) {
BigInteger expectedResult = valueOf(a).multiply(valueOf(b));
// TODO: cpovirk - Test against Math.multiplyExact instead?
BigInteger expectedResult = bigInt(a).multiply(bigInt(b));
boolean expectedSuccess = fitsInInt(expectedResult);
try {
assertEquals(a * b, IntMath.checkedMultiply(a, b));
assertEquals(a * b, checkedMultiply(a, b));
assertTrue(expectedSuccess);
} catch (ArithmeticException e) {
assertFalse(expectedSuccess);
Expand All @@ -481,7 +489,7 @@ public void testCheckedMultiply() {
public void testCheckedPow() {
for (int b : ALL_INTEGER_CANDIDATES) {
for (int k : EXPONENTS) {
BigInteger expectedResult = valueOf(b).pow(k);
BigInteger expectedResult = bigInt(b).pow(k);
boolean expectedSuccess = fitsInInt(expectedResult);
try {
assertEquals(b + "^" + k, force32(expectedResult.intValue()), IntMath.checkedPow(b, k));
Expand All @@ -499,7 +507,7 @@ public void testSaturatedAdd() {
for (int a : ALL_INTEGER_CANDIDATES) {
for (int b : ALL_INTEGER_CANDIDATES) {
assertOperationEquals(
a, b, "s+", saturatedCast(valueOf(a).add(valueOf(b))), IntMath.saturatedAdd(a, b));
a, b, "s+", saturatedCast(bigInt(a).add(bigInt(b))), IntMath.saturatedAdd(a, b));
}
}
}
Expand All @@ -513,7 +521,7 @@ public void testSaturatedSubtract() {
a,
b,
"s-",
saturatedCast(valueOf(a).subtract(valueOf(b))),
saturatedCast(bigInt(a).subtract(bigInt(b))),
IntMath.saturatedSubtract(a, b));
}
}
Expand All @@ -528,7 +536,7 @@ public void testSaturatedMultiply() {
a,
b,
"s*",
saturatedCast(valueOf(a).multiply(valueOf(b))),
saturatedCast(bigInt(a).multiply(bigInt(b))),
IntMath.saturatedMultiply(a, b));
}
}
Expand All @@ -539,13 +547,13 @@ public void testSaturatedPow() {
for (int a : ALL_INTEGER_CANDIDATES) {
for (int b : EXPONENTS) {
assertOperationEquals(
a, b, "s^", saturatedCast(valueOf(a).pow(b)), IntMath.saturatedPow(a, b));
a, b, "s^", saturatedCast(bigInt(a).pow(b)), IntMath.saturatedPow(a, b));
}
}
}

private static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
private static final BigInteger MIN_INT = BigInteger.valueOf(Integer.MIN_VALUE);
private static final BigInteger MAX_INT = bigInt(Integer.MAX_VALUE);
private static final BigInteger MIN_INT = bigInt(Integer.MIN_VALUE);

private static int saturatedCast(BigInteger big) {
if (big.compareTo(MAX_INT) > 0) {
Expand Down Expand Up @@ -663,8 +671,8 @@ private static void assertMean(int x, int y) {
* arithmetic.
*/
private static int computeMeanSafely(int x, int y) {
BigInteger bigX = BigInteger.valueOf(x);
BigInteger bigY = BigInteger.valueOf(y);
BigInteger bigX = bigInt(x);
BigInteger bigY = bigInt(y);
BigDecimal two = BigDecimal.valueOf(2); // Android doesn't have BigDecimal.TWO yet
BigDecimal bigMean = new BigDecimal(bigX.add(bigY)).divide(two, RoundingMode.FLOOR);
return bigMean.intValueExact();
Expand Down Expand Up @@ -712,6 +720,13 @@ public void testSaturatedAbs() {

private static int force32(int value) {
// GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
// TODO: b/404577035 - Remove this unless it's needed for J2CL.
// One of its users, testDivNonZero, is currently @GwtIncompatible, but maybe it WOULD need it?
// And if it's needed, maybe use our usual trick of ~~ instead?
return value & 0xffffffff;
}

private static BigInteger bigInt(long value) {
return BigInteger.valueOf(value);
}
}
Loading
Loading