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_BIGINTEGER_CANDIDATES;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.NONZERO_BIGINTEGER_CANDIDATES;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.math.MathTesting.POSITIVE_BIGINTEGER_CANDIDATES;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.BigInteger.ONE;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.BigInteger.TEN;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.BigInteger.ZERO;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.CEILING;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.DOWN;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.FLOOR;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.HALF_DOWN;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.HALF_EVEN;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.HALF_UP;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.UNNECESSARY;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.math.RoundingMode.UP;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.Arrays.asList;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible;
387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtIncompatible;
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
410888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase;
420888a09821a98ac0680fad765217302858e70fa4Paul Duffin
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.BigDecimal;
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.BigInteger;
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.math.RoundingMode;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for BigIntegerMath.
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
527dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible(emulated = true)
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class BigIntegerMathTest extends TestCase {
547dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConstantSqrt2PrecomputedBits() {
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(BigIntegerMath.sqrt(
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger.ZERO.setBit(2 * BigIntegerMath.SQRT2_PRECOMPUTE_THRESHOLD + 1), FLOOR),
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigIntegerMath.SQRT2_PRECOMPUTED_BITS);
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
607dd252788645e940eada959bdde927426e2531c9Paul Duffin
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIsPowerOfTwo() {
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : ALL_BIGINTEGER_CANDIDATES) {
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Checks for a single bit set.
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean expected = x.signum() > 0 & x.and(x.subtract(ONE)).equals(ZERO);
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expected, BigIntegerMath.isPowerOfTwo(x));
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2ZeroAlwaysThrows() {
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigIntegerMath.log2(ZERO, mode);
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2NegativeAlwaysThrows() {
797dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (RoundingMode mode : ALL_ROUNDING_MODES) {
807dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
817dd252788645e940eada959bdde927426e2531c9Paul Duffin        BigIntegerMath.log2(BigInteger.valueOf(-1), mode);
827dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail("Expected IllegalArgumentException");
837dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2Floor() {
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(FLOOR, DOWN)) {
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int result = BigIntegerMath.log2(x, mode);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(ZERO.setBit(result).compareTo(x) <= 0);
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(ZERO.setBit(result + 1).compareTo(x) > 0);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2Ceiling() {
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(CEILING, UP)) {
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int result = BigIntegerMath.log2(x, mode);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(ZERO.setBit(result).compareTo(x) >= 0);
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result == 0 || ZERO.setBit(result - 1).compareTo(x) < 0);
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of isPowerOfTwo(BigInteger).
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2Exact() {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // We only expect an exception if x was not a power of 2.
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean isPowerOf2 = BigIntegerMath.isPowerOfTwo(x);
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(x, ZERO.setBit(BigIntegerMath.log2(x, UNNECESSARY)));
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(isPowerOf2);
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(isPowerOf2);
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2HalfUp() {
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int result = BigIntegerMath.log2(x, HALF_UP);
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x2 = x.pow(2);
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 < 2^(2 * result + 1), or else we would have rounded up
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(ZERO.setBit(2 * result + 1).compareTo(x2) > 0);
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 >= 2^(2 * result - 1), or else we would have rounded down
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result == 0 || ZERO.setBit(2 * result - 1).compareTo(x2) <= 0);
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2HalfDown() {
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int result = BigIntegerMath.log2(x, HALF_DOWN);
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x2 = x.pow(2);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 <= 2^(2 * result + 1), or else we would have rounded up
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(ZERO.setBit(2 * result + 1).compareTo(x2) >= 0);
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 > 2^(2 * result - 1), or else we would have rounded down
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result == 0 || ZERO.setBit(2 * result - 1).compareTo(x2) < 0);
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of log2(BigInteger, {HALF_UP,HALF_DOWN}).
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog2HalfEven() {
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int halfEven = BigIntegerMath.log2(x, HALF_EVEN);
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Now figure out what rounding mode we should behave like (it depends if FLOOR was
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // odd/even).
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean floorWasEven = (BigIntegerMath.log2(x, FLOOR) & 1) == 0;
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(BigIntegerMath.log2(x, floorWasEven ? HALF_DOWN : HALF_UP), halfEven);
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10ZeroAlwaysThrows() {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigIntegerMath.log10(ZERO, mode);
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10NegativeAlwaysThrows() {
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (RoundingMode mode : ALL_ROUNDING_MODES) {
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin        BigIntegerMath.log10(BigInteger.valueOf(-1), mode);
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail("Expected IllegalArgumentException");
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1747dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10Floor() {
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(FLOOR, DOWN)) {
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int result = BigIntegerMath.log10(x, mode);
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(TEN.pow(result).compareTo(x) <= 0);
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(TEN.pow(result + 1).compareTo(x) > 0);
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1857dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10Ceiling() {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(CEILING, UP)) {
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int result = BigIntegerMath.log10(x, mode);
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(TEN.pow(result).compareTo(x) >= 0);
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result == 0 || TEN.pow(result - 1).compareTo(x) < 0);
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of log10(BigInteger, FLOOR).
1977dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10Exact() {
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int logFloor = BigIntegerMath.log10(x, FLOOR);
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean expectSuccess = TEN.pow(logFloor).equals(x);
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(logFloor, BigIntegerMath.log10(x, UNNECESSARY));
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(expectSuccess);
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(expectSuccess);
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10HalfUp() {
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int result = BigIntegerMath.log10(x, HALF_UP);
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x2 = x.pow(2);
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 < 10^(2 * result + 1), or else we would have rounded up
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(TEN.pow(2 * result + 1).compareTo(x2) > 0);
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 >= 10^(2 * result - 1), or else we would have rounded down
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result == 0 || TEN.pow(2 * result - 1).compareTo(x2) <= 0);
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2237dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10HalfDown() {
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int result = BigIntegerMath.log10(x, HALF_DOWN);
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x2 = x.pow(2);
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 <= 10^(2 * result + 1), or else we would have rounded up
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(TEN.pow(2 * result + 1).compareTo(x2) >= 0);
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // x^2 > 10^(2 * result - 1), or else we would have rounded down
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result == 0 || TEN.pow(2 * result - 1).compareTo(x2) < 0);
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of log10(BigInteger, {HALF_UP,HALF_DOWN}).
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10HalfEven() {
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int halfEven = BigIntegerMath.log10(x, HALF_EVEN);
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Now figure out what rounding mode we should behave like (it depends if FLOOR was
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // odd/even).
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean floorWasEven = (BigIntegerMath.log10(x, FLOOR) & 1) == 0;
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(BigIntegerMath.log10(x, floorWasEven ? HALF_DOWN : HALF_UP), halfEven);
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2477dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLog10TrivialOnPowerOf10() {
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BigInteger x = BigInteger.TEN.pow(100);
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(100, BigIntegerMath.log10(x, mode));
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtZeroAlwaysZero() {
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (RoundingMode mode : ALL_ROUNDING_MODES) {
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(ZERO, BigIntegerMath.sqrt(ZERO, mode));
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtNegativeAlwaysThrows() {
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (RoundingMode mode : ALL_ROUNDING_MODES) {
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin        BigIntegerMath.sqrt(BigInteger.valueOf(-1), mode);
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail("Expected IllegalArgumentException");
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtFloor() {
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(FLOOR, DOWN)) {
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger result = BigIntegerMath.sqrt(x, mode);
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.compareTo(ZERO) > 0);
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.pow(2).compareTo(x) <= 0);
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.add(ONE).pow(2).compareTo(x) > 0);
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtCeiling() {
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : asList(CEILING, UP)) {
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger result = BigIntegerMath.sqrt(x, mode);
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.compareTo(ZERO) > 0);
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.pow(2).compareTo(x) >= 0);
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(result.signum() == 0 || result.subtract(ONE).pow(2).compareTo(x) < 0);
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of sqrt(BigInteger, FLOOR).
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtExact() {
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger floor = BigIntegerMath.sqrt(x, FLOOR);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // We only expect an exception if x was not a perfect square.
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean isPerfectSquare = floor.pow(2).equals(x);
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(floor, BigIntegerMath.sqrt(x, UNNECESSARY));
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertTrue(isPerfectSquare);
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ArithmeticException e) {
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertFalse(isPerfectSquare);
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtHalfUp() {
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger result = BigIntegerMath.sqrt(x, HALF_UP);
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger plusHalfSquared = result.pow(2).add(result).shiftLeft(2).add(ONE);
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x4 = x.shiftLeft(2);
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // sqrt(x) < result + 0.5, so 4 * x < (result + 0.5)^2 * 4
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // (result + 0.5)^2 * 4 = (result^2 + result)*4 + 1
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(x4.compareTo(plusHalfSquared) < 0);
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger minusHalfSquared = result.pow(2).subtract(result).shiftLeft(2).add(ONE);
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // sqrt(x) > result - 0.5, so 4 * x > (result - 0.5)^2 * 4
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // (result - 0.5)^2 * 4 = (result^2 - result)*4 + 1
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result.equals(ZERO) || x4.compareTo(minusHalfSquared) >= 0);
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtHalfDown() {
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger result = BigIntegerMath.sqrt(x, HALF_DOWN);
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger plusHalfSquared = result.pow(2).add(result).shiftLeft(2).add(ONE);
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger x4 = x.shiftLeft(2);
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // sqrt(x) <= result + 0.5, so 4 * x <= (result + 0.5)^2 * 4
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // (result + 0.5)^2 * 4 = (result^2 + result)*4 + 1
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(x4.compareTo(plusHalfSquared) <= 0);
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger minusHalfSquared = result.pow(2).subtract(result).shiftLeft(2).add(ONE);
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // sqrt(x) > result - 0.5, so 4 * x > (result - 0.5)^2 * 4
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // (result - 0.5)^2 * 4 = (result^2 - result)*4 + 1
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(result.equals(ZERO) || x4.compareTo(minusHalfSquared) > 0);
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Relies on the correctness of sqrt(BigInteger, {HALF_UP,HALF_DOWN}).
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSqrtHalfEven() {
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      BigInteger halfEven = BigIntegerMath.sqrt(x, HALF_EVEN);
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Now figure out what rounding mode we should behave like (it depends if FLOOR was
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // odd/even).
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean floorWasOdd = BigIntegerMath.sqrt(x, FLOOR).testBit(0);
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(BigIntegerMath.sqrt(x, floorWasOdd ? HALF_UP : HALF_DOWN), halfEven);
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3567dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivNonZero() {
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          BigInteger expected =
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              new BigDecimal(p).divide(new BigDecimal(q), 0, mode).toBigIntegerExact();
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(expected, BigIntegerMath.divide(p, q, mode));
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3697dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivNonZeroExact() {
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean dividesEvenly = p.remainder(q).equals(ZERO);
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(p, BigIntegerMath.divide(p, q, UNNECESSARY).multiply(q));
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertTrue(dividesEvenly);
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(dividesEvenly);
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testZeroDivIsAlwaysZero() {
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(ZERO, BigIntegerMath.divide(ZERO, q, mode));
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("TODO")
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivByZeroAlwaysFails() {
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (BigInteger p : ALL_BIGINTEGER_CANDIDATES) {
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (RoundingMode mode : ALL_ROUNDING_MODES) {
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          BigIntegerMath.divide(p, ZERO, mode);
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fail("Expected ArithmeticException");
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException expected) {}
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFactorial() {
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BigInteger expected = BigInteger.ONE;
4087dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 1; i <= 200; i++) {
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      expected = expected.multiply(BigInteger.valueOf(i));
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(expected, BigIntegerMath.factorial(i));
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFactorial0() {
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(BigInteger.ONE, BigIntegerMath.factorial(0));
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFactorialNegative() {
4197dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
4207dd252788645e940eada959bdde927426e2531c9Paul Duffin      BigIntegerMath.factorial(-1);
4217dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail("Expected IllegalArgumentException");
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (IllegalArgumentException expected) {}
4237dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4247dd252788645e940eada959bdde927426e2531c9Paul Duffin
4257dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testBinomialSmall() {
4267dd252788645e940eada959bdde927426e2531c9Paul Duffin    runBinomialTest(0, 30);
4273c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("too slow")
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testBinomialLarge() {
4317dd252788645e940eada959bdde927426e2531c9Paul Duffin    runBinomialTest(31, 100);
4327dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4337dd252788645e940eada959bdde927426e2531c9Paul Duffin
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Depends on the correctness of BigIntegerMath.factorial
4357dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static void runBinomialTest(int firstN, int lastN) {
4367dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int n = firstN; n <= lastN; n++) {
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int k = 0; k <= n; k++) {
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigInteger expected = BigIntegerMath
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .factorial(n)
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .divide(BigIntegerMath.factorial(k))
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            .divide(BigIntegerMath.factorial(n - k));
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(expected, BigIntegerMath.binomial(n, k));
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testBinomialOutside() {
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int n = 0; n <= 50; n++) {
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigIntegerMath.binomial(n, -1);
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        BigIntegerMath.binomial(n, n + 1);
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Expected IllegalArgumentException");
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (IllegalArgumentException expected) {}
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4607dd252788645e940eada959bdde927426e2531c9Paul Duffin  @GwtIncompatible("NullPointerTester")
4617dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNullPointers() {
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    NullPointerTester tester = new NullPointerTester();
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(BigInteger.class, ONE);
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(int.class, 1);
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(long.class, 1L);
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.testAllPublicStaticMethods(BigIntegerMath.class);
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
469