11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.math;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_INTEGER_CANDIDATES;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_LONG_CANDIDATES;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.EXPONENTS;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.NEGATIVE_LONG_CANDIDATES;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.NONZERO_LONG_CANDIDATES;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.POSITIVE_LONG_CANDIDATES;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.BigInteger.valueOf;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.FLOOR;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.UNNECESSARY;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible;
347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtIncompatible;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
370888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase;
380888a09821a98ac0680fad765217302858e70fa4Paul Duffin
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.BigDecimal;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.BigInteger;
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.RoundingMode;
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for LongMath.
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
487dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible(emulated = true)
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class LongMathTest extends TestCase {
507dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantMaxPowerOfSqrt2Unsigned() {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Long.SIZE - 1), FLOOR).longValue(),
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.MAX_POWER_OF_SQRT2_UNSIGNED);
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
567dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
577dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testMaxLog10ForLeadingZeros() {
587dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < Long.SIZE; i++) {
597dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(
607dd252788645e940eada959bdde927426e2531c9Paul Duffin          BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Long.SIZE - i), FLOOR),
617dd252788645e940eada959bdde927426e2531c9Paul Duffin          LongMath.maxLog10ForLeadingZeros[i]);
627dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
637dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
647dd252788645e940eada959bdde927426e2531c9Paul Duffin
657dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsPowersOf10() {
677dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < LongMath.powersOf10.length; i++) {
687dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(LongMath.checkedPow(10, i), LongMath.powersOf10[i]);
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
717dd252788645e940eada959bdde927426e2531c9Paul Duffin      LongMath.checkedPow(10, LongMath.powersOf10.length);
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected ArithmeticException");
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ArithmeticException expected) {}
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
767dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsHalfPowersOf10() {
787dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < LongMath.halfPowersOf10.length; i++) {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR),
807dd252788645e940eada959bdde927426e2531c9Paul Duffin          BigInteger.valueOf(LongMath.halfPowersOf10[i]));
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BigInteger nextBigger =
837dd252788645e940eada959bdde927426e2531c9Paul Duffin        BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * LongMath.halfPowersOf10.length + 1), FLOOR);
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(nextBigger.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0);
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
877dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsSqrtMaxLong() {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(LongMath.sqrt(Long.MAX_VALUE, FLOOR), LongMath.FLOOR_SQRT_MAX_LONG);
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
927dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsFactorials() {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long expected = 1;
957dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < LongMath.factorials.length; i++, expected *= i) {
967dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(expected, LongMath.factorials[i]);
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      LongMath.checkedMultiply(
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin          LongMath.factorials[LongMath.factorials.length - 1], LongMath.factorials.length);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected ArithmeticException");
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ArithmeticException expect) {}
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsBiggestBinomials() {
1077dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int k = 0; k < LongMath.biggestBinomials.length; k++) {
1087dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k], k)));
1097dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(LongMath.biggestBinomials[k] == Integer.MAX_VALUE
1107dd252788645e940eada959bdde927426e2531c9Paul Duffin          || !fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k] + 1, k)));
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // In the first case, any long is valid; in the second, we want to test that the next-bigger
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // long overflows.
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin    int k = LongMath.biggestBinomials.length;
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(fitsInLong(BigIntegerMath.binomial(2 * k, k)));
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // 2 * k is the smallest value for which we don't replace k with (n-k).
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1197dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantsBiggestSimpleBinomials() {
1217dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int k = 0; k < LongMath.biggestSimpleBinomials.length; k++) {
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(LongMath.biggestSimpleBinomials[k] <= LongMath.biggestBinomials[k]);
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin      simpleBinomial(LongMath.biggestSimpleBinomials[k], k); // mustn't throw
1247dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (LongMath.biggestSimpleBinomials[k] < Integer.MAX_VALUE) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // unless all n are fair game with this k
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin          simpleBinomial(LongMath.biggestSimpleBinomials[k] + 1, k);
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected ArithmeticException");
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException expected) {}
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin      int k = LongMath.biggestSimpleBinomials.length;
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      simpleBinomial(2 * k, k);
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // 2 * k is the smallest value for which we don't replace k with (n-k).
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected ArithmeticException");
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ArithmeticException expected) {}
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testLessThanBranchFree() {
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (long x : ALL_LONG_CANDIDATES) {
1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (long y : ALL_LONG_CANDIDATES) {
1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        BigInteger difference = BigInteger.valueOf(x).subtract(BigInteger.valueOf(y));
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (fitsInLong(difference)) {
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin          int expected = (x < y) ? 1 : 0;
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin          int actual = LongMath.lessThanBranchFree(x, y);
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin          assertEquals(expected, actual);
1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Throws an ArithmeticException if "the simple implementation" of binomial coefficients overflows
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private long simpleBinomial(int n, int k) {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long accum = 1;
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < k; i++) {
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      accum = LongMath.checkedMultiply(accum, n - i);
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      accum /= i + 1;
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return accum;
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("java.math.BigInteger")
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIsPowerOfTwo() {
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Checks for a single bit set.
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin      BigInteger bigX = BigInteger.valueOf(x);
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin      boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expected, LongMath.isPowerOfTwo(x));
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2ZeroAlwaysThrows() {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.log2(0L, mode);
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2NegativeAlwaysThrows() {
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : NEGATIVE_LONG_CANDIDATES) {
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.log2(x, mode);
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected IllegalArgumentException");
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (IllegalArgumentException expected) {}
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /* Relies on the correctness of BigIntegerMath.log2 for all modes except UNNECESSARY. */
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2MatchesBigInteger() {
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // The BigInteger implementation is tested separately, use it as the reference.
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(BigIntegerMath.log2(valueOf(x), mode), LongMath.log2(x, mode));
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /* Relies on the correctness of isPowerOfTwo(long). */
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2Exact() {
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // We only expect an exception if x was not a power of 2.
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean isPowerOf2 = LongMath.isPowerOfTwo(x);
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(x, 1L << LongMath.log2(x, UNNECESSARY));
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(isPowerOf2);
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(isPowerOf2);
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2187dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10ZeroAlwaysThrows() {
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.log10(0L, mode);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2287dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10NegativeAlwaysThrows() {
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : NEGATIVE_LONG_CANDIDATES) {
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.log10(x, mode);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected IllegalArgumentException");
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (IllegalArgumentException expected) {}
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of BigIntegerMath.log10 for all modes except UNNECESSARY.
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10MatchesBigInteger() {
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(BigIntegerMath.log10(valueOf(x), mode), LongMath.log10(x, mode));
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of log10(long, FLOOR) and of pow(long, int).
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10Exact() {
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int floor = LongMath.log10(x, FLOOR);
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean expectSuccess = LongMath.pow(10, floor) == x;
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(floor, LongMath.log10(x, UNNECESSARY));
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(expectSuccess);
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(expectSuccess);
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10TrivialOnPowerOf10() {
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long x = 1000000000000L;
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(12, LongMath.log10(x, mode));
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtNegativeAlwaysThrows() {
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : NEGATIVE_LONG_CANDIDATES) {
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.sqrt(x, mode);
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected IllegalArgumentException");
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (IllegalArgumentException expected) {}
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of BigIntegerMath.sqrt for all modes except UNNECESSARY.
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtMatchesBigInteger() {
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // Promote the long value (rather than using longValue() on the expected value) to avoid
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // any risk of truncation which could lead to a false positive.
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(BigIntegerMath.sqrt(valueOf(x), mode), valueOf(LongMath.sqrt(x, mode)));
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /* Relies on the correctness of sqrt(long, FLOOR). */
2987dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtExactMatchesFloorOrThrows() {
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : POSITIVE_LONG_CANDIDATES) {
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long sqrtFloor = LongMath.sqrt(x, FLOOR);
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // We only expect an exception if x was not a perfect square.
3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      boolean isPerfectSquare = (sqrtFloor * sqrtFloor == x);
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin        assertEquals(sqrtFloor, LongMath.sqrt(x, UNNECESSARY));
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(isPerfectSquare);
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(isPerfectSquare);
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPow() {
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long i : ALL_LONG_CANDIDATES) {
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int exp : EXPONENTS) {
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(LongMath.pow(i, exp), valueOf(i)
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .pow(exp)
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .longValue());
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivNonZero() {
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long p : NONZERO_LONG_CANDIDATES) {
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long q : NONZERO_LONG_CANDIDATES) {
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          long expected =
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              new BigDecimal(valueOf(p)).divide(new BigDecimal(valueOf(q)), 0, mode).longValue();
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(expected, LongMath.divide(p, q, mode));
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivNonZeroExact() {
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long p : NONZERO_LONG_CANDIDATES) {
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long q : NONZERO_LONG_CANDIDATES) {
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean dividesEvenly = (p % q) == 0L;
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(p, LongMath.divide(p, q, UNNECESSARY) * q);
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(dividesEvenly);
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(dividesEvenly);
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3537dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testZeroDivIsAlwaysZero() {
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long q : NONZERO_LONG_CANDIDATES) {
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(0L, LongMath.divide(0L, q, mode));
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3627dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivByZeroAlwaysFails() {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long p : ALL_LONG_CANDIDATES) {
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.divide(p, 0L, mode);
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected ArithmeticException");
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException expected) {}
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3747dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIntMod() {
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int m : POSITIVE_INTEGER_CANDIDATES) {
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(valueOf(x)
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .mod(valueOf(m))
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .intValue(), LongMath.mod(x, m));
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIntModNegativeModulusFails() {
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int m : NEGATIVE_INTEGER_CANDIDATES) {
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.mod(x, m);
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected ArithmeticException");
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException expected) {}
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3977dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIntModZeroModulusFails() {
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.mod(x, 0);
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected AE");
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException expected) {}
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4077dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMod() {
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long m : POSITIVE_LONG_CANDIDATES) {
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(valueOf(x)
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .mod(valueOf(m))
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .longValue(), LongMath.mod(x, m));
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4187dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testModNegativeModulusFails() {
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long x : ALL_LONG_CANDIDATES) {
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long m : NEGATIVE_LONG_CANDIDATES) {
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          LongMath.mod(x, m);
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected ArithmeticException");
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException expected) {}
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testGCDExhaustive() {
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : POSITIVE_LONG_CANDIDATES) {
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : POSITIVE_LONG_CANDIDATES) {
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(valueOf(a).gcd(valueOf(b)), valueOf(LongMath.gcd(a, b)));
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4387dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testGCDZero() {
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : POSITIVE_LONG_CANDIDATES) {
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(a, LongMath.gcd(a, 0));
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(a, LongMath.gcd(0, a));
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(0, LongMath.gcd(0, 0));
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4477dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testGCDNegativePositiveThrows() {
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : NEGATIVE_LONG_CANDIDATES) {
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.gcd(a, 3);
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.gcd(3, a);
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4617dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testGCDNegativeZeroThrows() {
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : NEGATIVE_LONG_CANDIDATES) {
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.gcd(a, 0);
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.gcd(0, a);
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4757dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedAdd() {
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : ALL_INTEGER_CANDIDATES) {
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : ALL_INTEGER_CANDIDATES) {
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expectedResult = valueOf(a).add(valueOf(b));
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean expectedSuccess = fitsInLong(expectedResult);
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(a + b, LongMath.checkedAdd(a, b));
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(expectedSuccess);
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(expectedSuccess);
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4917dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedSubtract() {
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : ALL_INTEGER_CANDIDATES) {
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : ALL_INTEGER_CANDIDATES) {
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expectedResult = valueOf(a).subtract(valueOf(b));
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean expectedSuccess = fitsInLong(expectedResult);
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(a - b, LongMath.checkedSubtract(a, b));
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(expectedSuccess);
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(expectedSuccess);
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5077dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedMultiply() {
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : ALL_INTEGER_CANDIDATES) {
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : ALL_INTEGER_CANDIDATES) {
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expectedResult = valueOf(a).multiply(valueOf(b));
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean expectedSuccess = fitsInLong(expectedResult);
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(a * b, LongMath.checkedMultiply(a, b));
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(expectedSuccess);
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(expectedSuccess);
5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5237dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCheckedPow() {
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long b : ALL_INTEGER_CANDIDATES) {
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int exp : EXPONENTS) {
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expectedResult = valueOf(b).pow(exp);
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean expectedSuccess = fitsInLong(expectedResult);
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(expectedResult.longValue(), LongMath.checkedPow(b, exp));
5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(expectedSuccess);
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(expectedSuccess);
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Depends on the correctness of BigIntegerMath.factorial.
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFactorial() {
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n = 0; n <= 50; n++) {
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger expectedBig = BigIntegerMath.factorial(n);
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      long expectedLong = fitsInLong(expectedBig) ? expectedBig.longValue() : Long.MAX_VALUE;
5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expectedLong, LongMath.factorial(n));
5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFactorialNegative() {
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n : NEGATIVE_INTEGER_CANDIDATES) {
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.factorial(n);
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Depends on the correctness of BigIntegerMath.binomial.
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testBinomial() {
5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n = 0; n <= 70; n++) {
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int k = 0; k <= n; k++) {
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expectedBig = BigIntegerMath.binomial(n, k);
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        long expectedLong = fitsInLong(expectedBig) ? expectedBig.longValue() : Long.MAX_VALUE;
5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(expectedLong, LongMath.binomial(n, k));
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("Slow")
5717dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testBinomial_exhaustiveNotOverflowing() {
5727dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Tests all of the inputs to LongMath.binomial that won't cause it to overflow, that weren't
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin    // tested in the previous method, for k >= 3.
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int k = 3; k < LongMath.biggestBinomials.length; k++) {
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (int n = 70; n <= LongMath.biggestBinomials[k]; n++) {
5767dd252788645e940eada959bdde927426e2531c9Paul Duffin        assertEquals(BigIntegerMath.binomial(n, k).longValue(), LongMath.binomial(n, k));
5777dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5797dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5807dd252788645e940eada959bdde927426e2531c9Paul Duffin
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testBinomialOutside() {
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n = 0; n <= 50; n++) {
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.binomial(n, -1);
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.binomial(n, n + 1);
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testBinomialNegative() {
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n : NEGATIVE_INTEGER_CANDIDATES) {
5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        LongMath.binomial(n, 0);
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6030888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @GwtIncompatible("far too slow")
6040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testSqrtOfPerfectSquareAsDoubleIsPerfect() {
6050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // This takes just over a minute on my machine.
6060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (long n = 0; n <= LongMath.FLOOR_SQRT_MAX_LONG; n++) {
6070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long actual = (long) Math.sqrt(n * n);
6080888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(actual == n);
6090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6100888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6110888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6120888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testSqrtOfLongIsAtMostFloorSqrtMaxLong() {
6130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long sqrtMaxLong = (long) Math.sqrt(Long.MAX_VALUE);
6140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(sqrtMaxLong <= LongMath.FLOOR_SQRT_MAX_LONG);
6150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6177dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("java.math.BigInteger")
6187dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testMean() {
6197dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Odd-sized ranges have an obvious mean
6207dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(2, 1, 3);
6217dd252788645e940eada959bdde927426e2531c9Paul Duffin
6227dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(-2, -3, -1);
6237dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(0, -1, 1);
6247dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(1, -1, 3);
6257dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean((1L << 62) - 1, -1, Long.MAX_VALUE);
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Even-sized ranges should prefer the lower mean
6287dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(2, 1, 4);
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(-3, -4, -1);
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(0, -1, 2);
6317dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(0, Long.MIN_VALUE + 2, Long.MAX_VALUE);
6327dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(0, 0, 1);
6337dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(-1, -1, 0);
6347dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(-1, Long.MIN_VALUE, Long.MAX_VALUE);
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin    // x == y == mean
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(1, 1, 1);
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(0, 0, 0);
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(-1, -1, -1);
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE);
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE);
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin
6437dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Exhaustive checks
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (long x : ALL_LONG_CANDIDATES) {
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (long y : ALL_LONG_CANDIDATES) {
6467dd252788645e940eada959bdde927426e2531c9Paul Duffin        assertMean(x, y);
6477dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6487dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6507dd252788645e940eada959bdde927426e2531c9Paul Duffin
6517dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Helper method that asserts the arithmetic mean of x and y is equal
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin   * to the expectedMean.
6547dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static void assertMean(long expectedMean, long x, long y) {
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals("The expectedMean should be the same as computeMeanSafely",
6577dd252788645e940eada959bdde927426e2531c9Paul Duffin        expectedMean, computeMeanSafely(x, y));
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertMean(x, y);
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6607dd252788645e940eada959bdde927426e2531c9Paul Duffin
6617dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Helper method that asserts the arithmetic mean of x and y is equal
6637dd252788645e940eada959bdde927426e2531c9Paul Duffin   *to the result of computeMeanSafely.
6647dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
6657dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static void assertMean(long x, long y) {
6667dd252788645e940eada959bdde927426e2531c9Paul Duffin    long expectedMean = computeMeanSafely(x, y);
6677dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(expectedMean, LongMath.mean(x, y));
6687dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals("The mean of x and y should equal the mean of y and x",
6697dd252788645e940eada959bdde927426e2531c9Paul Duffin        expectedMean, LongMath.mean(y, x));
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin
6727dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
6737dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Computes the mean in a way that is obvious and resilient to
6747dd252788645e940eada959bdde927426e2531c9Paul Duffin   * overflow by using BigInteger arithmetic.
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static long computeMeanSafely(long x, long y) {
6777dd252788645e940eada959bdde927426e2531c9Paul Duffin    BigInteger bigX = BigInteger.valueOf(x);
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin    BigInteger bigY = BigInteger.valueOf(y);
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin    BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin        .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin    // parseInt blows up on overflow as opposed to intValue() which does not.
6827dd252788645e940eada959bdde927426e2531c9Paul Duffin    return Long.parseLong(bigMean.toString());
6837dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6847dd252788645e940eada959bdde927426e2531c9Paul Duffin
6857dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean fitsInLong(BigInteger big) {
6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return big.bitLength() <= 63;
6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6897dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("NullPointerTester")
6907dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNullPointers() {
6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    NullPointerTester tester = new NullPointerTester();
6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(int.class, 1);
6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(long.class, 1L);
6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.testAllPublicStaticMethods(LongMath.class);
6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
697