Home | History | Annotate | Download | only in math
      1 /*
      2  * Copyright (C) 2011 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.math;
     18 
     19 import static com.google.common.math.MathTesting.ALL_INTEGER_CANDIDATES;
     20 import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
     21 import static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
     22 import static com.google.common.math.MathTesting.EXPONENTS;
     23 import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
     24 import static com.google.common.math.MathTesting.NONZERO_INTEGER_CANDIDATES;
     25 import static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
     26 import static com.google.common.math.TestPlatform.intsCanGoOutOfRange;
     27 import static java.math.BigInteger.valueOf;
     28 import static java.math.RoundingMode.FLOOR;
     29 import static java.math.RoundingMode.UNNECESSARY;
     30 
     31 import com.google.common.annotations.GwtCompatible;
     32 import com.google.common.annotations.GwtIncompatible;
     33 import com.google.common.testing.NullPointerTester;
     34 
     35 import junit.framework.TestCase;
     36 
     37 import java.math.BigDecimal;
     38 import java.math.BigInteger;
     39 import java.math.RoundingMode;
     40 
     41 /**
     42  * Tests for {@link IntMath}.
     43  *
     44  * @author Louis Wasserman
     45  */
     46 @GwtCompatible(emulated = true)
     47 public class IntMathTest extends TestCase {
     48   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
     49   public void testConstantMaxPowerOfSqrt2Unsigned() {
     50     assertEquals(
     51         BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Integer.SIZE - 1), FLOOR).intValue(),
     52         IntMath.MAX_POWER_OF_SQRT2_UNSIGNED);
     53   }
     54 
     55   @GwtIncompatible("pow()")
     56   public void testConstantsPowersOf10() {
     57     for (int i = 0; i < IntMath.powersOf10.length - 1; i++) {
     58       assertEquals(IntMath.pow(10, i), IntMath.powersOf10[i]);
     59     }
     60   }
     61 
     62   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
     63   public void testMaxLog10ForLeadingZeros() {
     64     for (int i = 0; i < Integer.SIZE; i++) {
     65       assertEquals(
     66           BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Integer.SIZE - i), FLOOR),
     67           IntMath.maxLog10ForLeadingZeros[i]);
     68     }
     69   }
     70 
     71   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
     72   public void testConstantsHalfPowersOf10() {
     73     for (int i = 0; i < IntMath.halfPowersOf10.length; i++) {
     74       assert IntMath.halfPowersOf10[i]
     75           == Math.min(Integer.MAX_VALUE,
     76               BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR).longValue());
     77     }
     78   }
     79 
     80   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
     81   public void testConstantsBiggestBinomials() {
     82     for (int k = 0; k < IntMath.biggestBinomials.length; k++) {
     83       assertTrue(fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k], k)));
     84       assertTrue(IntMath.biggestBinomials[k] == Integer.MAX_VALUE
     85           || !fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k] + 1, k)));
     86       // In the first case, any int is valid; in the second, we want to test that the next-bigger
     87       // int overflows.
     88     }
     89     assertFalse(
     90         fitsInInt(BigIntegerMath.binomial(
     91             2 * IntMath.biggestBinomials.length, IntMath.biggestBinomials.length)));
     92   }
     93 
     94   @GwtIncompatible("sqrt")
     95   public void testPowersSqrtMaxInt() {
     96     assertEquals(IntMath.sqrt(Integer.MAX_VALUE, FLOOR), IntMath.FLOOR_SQRT_MAX_INT);
     97   }
     98 
     99   public void testLessThanBranchFree() {
    100     for (int x : ALL_INTEGER_CANDIDATES) {
    101       for (int y : ALL_INTEGER_CANDIDATES) {
    102         if (LongMath.fitsInInt((long) x - y)) {
    103           int expected = (x < y) ? 1 : 0;
    104           int actual = IntMath.lessThanBranchFree(x, y);
    105           assertEquals(expected, actual);
    106         }
    107       }
    108     }
    109   }
    110 
    111   @GwtIncompatible("java.math.BigInteger")
    112   public void testIsPowerOfTwo() {
    113     for (int x : ALL_INTEGER_CANDIDATES) {
    114       // Checks for a single bit set.
    115       BigInteger bigX = BigInteger.valueOf(x);
    116       boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
    117       assertEquals(expected, IntMath.isPowerOfTwo(x));
    118     }
    119   }
    120 
    121   public void testLog2ZeroAlwaysThrows() {
    122     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    123       try {
    124         IntMath.log2(0, mode);
    125         fail("Expected IllegalArgumentException");
    126       } catch (IllegalArgumentException expected) {}
    127     }
    128   }
    129 
    130   public void testLog2NegativeAlwaysThrows() {
    131     for (int x : NEGATIVE_INTEGER_CANDIDATES) {
    132       for (RoundingMode mode : ALL_ROUNDING_MODES) {
    133         try {
    134           IntMath.log2(x, mode);
    135           fail("Expected IllegalArgumentException");
    136         } catch (IllegalArgumentException expected) {}
    137       }
    138     }
    139   }
    140 
    141   // Relies on the correctness of BigIntegrerMath.log2 for all modes except UNNECESSARY.
    142   public void testLog2MatchesBigInteger() {
    143     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    144       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    145         assertEquals(BigIntegerMath.log2(valueOf(x), mode), IntMath.log2(x, mode));
    146       }
    147     }
    148   }
    149 
    150   // Relies on the correctness of isPowerOfTwo(int).
    151   public void testLog2Exact() {
    152     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    153       // We only expect an exception if x was not a power of 2.
    154       boolean isPowerOf2 = IntMath.isPowerOfTwo(x);
    155       try {
    156         assertEquals(x, 1 << IntMath.log2(x, UNNECESSARY));
    157         assertTrue(isPowerOf2);
    158       } catch (ArithmeticException e) {
    159         assertFalse(isPowerOf2);
    160       }
    161     }
    162   }
    163 
    164   @GwtIncompatible("log10")
    165   public void testLog10ZeroAlwaysThrows() {
    166     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    167       try {
    168         IntMath.log10(0, mode);
    169         fail("Expected IllegalArgumentException");
    170       } catch (IllegalArgumentException expected) {}
    171     }
    172   }
    173 
    174   @GwtIncompatible("log10")
    175   public void testLog10NegativeAlwaysThrows() {
    176     for (int x : NEGATIVE_INTEGER_CANDIDATES) {
    177       for (RoundingMode mode : ALL_ROUNDING_MODES) {
    178         try {
    179           IntMath.log10(x, mode);
    180           fail("Expected IllegalArgumentException");
    181         } catch (IllegalArgumentException expected) {}
    182       }
    183     }
    184   }
    185 
    186   // Relies on the correctness of BigIntegerMath.log10 for all modes except UNNECESSARY.
    187   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
    188   public void testLog10MatchesBigInteger() {
    189     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    190       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    191         // The BigInteger implementation is tested separately, use it as the reference.
    192         assertEquals(BigIntegerMath.log10(valueOf(x), mode), IntMath.log10(x, mode));
    193       }
    194     }
    195   }
    196 
    197   // Relies on the correctness of log10(int, FLOOR) and of pow(int, int).
    198   @GwtIncompatible("pow()")
    199   public void testLog10Exact() {
    200     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    201       int floor = IntMath.log10(x, FLOOR);
    202       boolean expectSuccess = IntMath.pow(10, floor) == x;
    203       try {
    204         assertEquals(floor, IntMath.log10(x, UNNECESSARY));
    205         assertTrue(expectSuccess);
    206       } catch (ArithmeticException e) {
    207         assertFalse(expectSuccess);
    208       }
    209     }
    210   }
    211 
    212   @GwtIncompatible("log10")
    213   public void testLog10TrivialOnPowerOfTen() {
    214     int x = 1000000;
    215     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    216       assertEquals(6, IntMath.log10(x, mode));
    217     }
    218   }
    219 
    220   // Simple test to cover sqrt(0) for all types and all modes.
    221   @GwtIncompatible("sqrt")
    222   public void testSqrtZeroAlwaysZero() {
    223     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    224       assertEquals(0, IntMath.sqrt(0, mode));
    225     }
    226   }
    227 
    228   @GwtIncompatible("sqrt")
    229   public void testSqrtNegativeAlwaysThrows() {
    230     for (int x : NEGATIVE_INTEGER_CANDIDATES) {
    231       for (RoundingMode mode : RoundingMode.values()) {
    232         try {
    233           IntMath.sqrt(x, mode);
    234           fail("Expected IllegalArgumentException");
    235         } catch (IllegalArgumentException expected) {}
    236       }
    237     }
    238   }
    239 
    240   /* Relies on the correctness of BigIntegerMath.sqrt for all modes except UNNECESSARY. */
    241   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
    242   public void testSqrtMatchesBigInteger() {
    243     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    244       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    245         // The BigInteger implementation is tested separately, use it as the reference.
    246         // Promote the int value (rather than using intValue() on the expected value) to avoid
    247         // any risk of truncation which could lead to a false positive.
    248         assertEquals(BigIntegerMath.sqrt(valueOf(x), mode), valueOf(IntMath.sqrt(x, mode)));
    249       }
    250     }
    251   }
    252 
    253   /* Relies on the correctness of sqrt(int, FLOOR). */
    254   @GwtIncompatible("sqrt")
    255   public void testSqrtExactMatchesFloorOrThrows() {
    256     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    257       int floor = IntMath.sqrt(x, FLOOR);
    258       // We only expect an exception if x was not a perfect square.
    259       boolean isPerfectSquare = (floor * floor == x);
    260       try {
    261         assertEquals(floor, IntMath.sqrt(x, UNNECESSARY));
    262         assertTrue(isPerfectSquare);
    263       } catch (ArithmeticException e) {
    264         assertFalse(isPerfectSquare);
    265       }
    266     }
    267   }
    268 
    269   @GwtIncompatible("2147483646^2 expected=4")
    270   public void testPow() {
    271     for (int i : ALL_INTEGER_CANDIDATES) {
    272       for (int pow : EXPONENTS) {
    273         assertEquals(i + "^" + pow, BigInteger.valueOf(i).pow(pow).intValue(), IntMath.pow(i, pow));
    274       }
    275     }
    276   }
    277 
    278   public void testDivNonZero() {
    279     for (int p : NONZERO_INTEGER_CANDIDATES) {
    280       for (int q : NONZERO_INTEGER_CANDIDATES) {
    281         for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    282           // Skip some tests that fail due to GWT's non-compliant int implementation.
    283           // TODO(cpovirk): does this test fail for only some rounding modes or for all?
    284           if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
    285             continue;
    286           }
    287           int expected =
    288               new BigDecimal(valueOf(p)).divide(new BigDecimal(valueOf(q)), 0, mode).intValue();
    289           assertEquals(p + "/" + q, force32(expected), IntMath.divide(p, q, mode));
    290         }
    291       }
    292     }
    293   }
    294 
    295   public void testDivNonZeroExact() {
    296     for (int p : NONZERO_INTEGER_CANDIDATES) {
    297       for (int q : NONZERO_INTEGER_CANDIDATES) {
    298         // Skip some tests that fail due to GWT's non-compliant int implementation.
    299         if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
    300           continue;
    301         }
    302         boolean dividesEvenly = (p % q) == 0;
    303         try {
    304           assertEquals(p + "/" + q, p, IntMath.divide(p, q, UNNECESSARY) * q);
    305           assertTrue(p + "/" + q + " not expected to divide evenly", dividesEvenly);
    306         } catch (ArithmeticException e) {
    307           assertFalse(p + "/" + q + " expected to divide evenly", dividesEvenly);
    308         }
    309       }
    310     }
    311   }
    312 
    313   public void testZeroDivIsAlwaysZero() {
    314     for (int q : NONZERO_INTEGER_CANDIDATES) {
    315       for (RoundingMode mode : ALL_ROUNDING_MODES) {
    316         assertEquals(0, IntMath.divide(0, q, mode));
    317       }
    318     }
    319   }
    320 
    321   public void testDivByZeroAlwaysFails() {
    322     for (int p : ALL_INTEGER_CANDIDATES) {
    323       for (RoundingMode mode : ALL_ROUNDING_MODES) {
    324         try {
    325           IntMath.divide(p, 0, mode);
    326           fail("Expected ArithmeticException");
    327         } catch (ArithmeticException expected) {}
    328       }
    329     }
    330   }
    331 
    332   public void testMod() {
    333     for (int x : ALL_INTEGER_CANDIDATES) {
    334       for (int m : POSITIVE_INTEGER_CANDIDATES) {
    335         assertEquals(valueOf(x).mod(valueOf(m)).intValue(), IntMath.mod(x, m));
    336       }
    337     }
    338   }
    339 
    340   public void testModNegativeModulusFails() {
    341     for (int x : POSITIVE_INTEGER_CANDIDATES) {
    342       for (int m : NEGATIVE_INTEGER_CANDIDATES) {
    343         try {
    344           IntMath.mod(x, m);
    345           fail("Expected ArithmeticException");
    346         } catch (ArithmeticException expected) {}
    347       }
    348     }
    349   }
    350 
    351   public void testModZeroModulusFails() {
    352     for (int x : ALL_INTEGER_CANDIDATES) {
    353       try {
    354         IntMath.mod(x, 0);
    355         fail("Expected ArithmeticException");
    356       } catch (ArithmeticException expected) {}
    357     }
    358   }
    359 
    360   public void testGCD() {
    361     for (int a : POSITIVE_INTEGER_CANDIDATES) {
    362       for (int b : POSITIVE_INTEGER_CANDIDATES) {
    363         assertEquals(valueOf(a).gcd(valueOf(b)), valueOf(IntMath.gcd(a, b)));
    364       }
    365     }
    366   }
    367 
    368   public void testGCDZero() {
    369     for (int a : POSITIVE_INTEGER_CANDIDATES) {
    370       assertEquals(a, IntMath.gcd(a, 0));
    371       assertEquals(a, IntMath.gcd(0, a));
    372     }
    373     assertEquals(0, IntMath.gcd(0, 0));
    374   }
    375 
    376   public void testGCDNegativePositiveThrows() {
    377     for (int a : NEGATIVE_INTEGER_CANDIDATES) {
    378       try {
    379         IntMath.gcd(a, 3);
    380         fail("Expected IllegalArgumentException");
    381       } catch (IllegalArgumentException expected) {}
    382       try {
    383         IntMath.gcd(3, a);
    384         fail("Expected IllegalArgumentException");
    385       } catch (IllegalArgumentException expected) {}
    386     }
    387   }
    388 
    389   public void testGCDNegativeZeroThrows() {
    390     for (int a : NEGATIVE_INTEGER_CANDIDATES) {
    391       try {
    392         IntMath.gcd(a, 0);
    393         fail("Expected IllegalArgumentException");
    394       } catch (IllegalArgumentException expected) {}
    395       try {
    396         IntMath.gcd(0, a);
    397         fail("Expected IllegalArgumentException");
    398       } catch (IllegalArgumentException expected) {}
    399     }
    400   }
    401 
    402   public void testCheckedAdd() {
    403     for (int a : ALL_INTEGER_CANDIDATES) {
    404       for (int b : ALL_INTEGER_CANDIDATES) {
    405         BigInteger expectedResult = valueOf(a).add(valueOf(b));
    406         boolean expectedSuccess = fitsInInt(expectedResult);
    407         try {
    408           assertEquals(a + b, IntMath.checkedAdd(a, b));
    409           assertTrue(expectedSuccess);
    410         } catch (ArithmeticException e) {
    411           assertFalse(expectedSuccess);
    412         }
    413       }
    414     }
    415   }
    416 
    417   public void testCheckedSubtract() {
    418     for (int a : ALL_INTEGER_CANDIDATES) {
    419       for (int b : ALL_INTEGER_CANDIDATES) {
    420         BigInteger expectedResult = valueOf(a).subtract(valueOf(b));
    421         boolean expectedSuccess = fitsInInt(expectedResult);
    422         try {
    423           assertEquals(a - b, IntMath.checkedSubtract(a, b));
    424           assertTrue(expectedSuccess);
    425         } catch (ArithmeticException e) {
    426           assertFalse(expectedSuccess);
    427         }
    428       }
    429     }
    430   }
    431 
    432   public void testCheckedMultiply() {
    433     for (int a : ALL_INTEGER_CANDIDATES) {
    434       for (int b : ALL_INTEGER_CANDIDATES) {
    435         BigInteger expectedResult = valueOf(a).multiply(valueOf(b));
    436         boolean expectedSuccess = fitsInInt(expectedResult);
    437         try {
    438           assertEquals(a * b, IntMath.checkedMultiply(a, b));
    439           assertTrue(expectedSuccess);
    440         } catch (ArithmeticException e) {
    441           assertFalse(expectedSuccess);
    442         }
    443       }
    444     }
    445   }
    446 
    447   public void testCheckedPow() {
    448     for (int b : ALL_INTEGER_CANDIDATES) {
    449       for (int k : EXPONENTS) {
    450         BigInteger expectedResult = valueOf(b).pow(k);
    451         boolean expectedSuccess = fitsInInt(expectedResult);
    452         try {
    453           assertEquals(b + "^" + k, force32(expectedResult.intValue()), IntMath.checkedPow(b, k));
    454           assertTrue(b + "^" + k + " should have succeeded", expectedSuccess);
    455         } catch (ArithmeticException e) {
    456           assertFalse(b + "^" + k + " should have failed", expectedSuccess);
    457         }
    458       }
    459     }
    460   }
    461 
    462   // Depends on the correctness of BigIntegerMath.factorial.
    463   public void testFactorial() {
    464     for (int n = 0; n <= 50; n++) {
    465       BigInteger expectedBig = BigIntegerMath.factorial(n);
    466       int expectedInt = fitsInInt(expectedBig) ? expectedBig.intValue() : Integer.MAX_VALUE;
    467       assertEquals(expectedInt, IntMath.factorial(n));
    468     }
    469   }
    470 
    471   public void testFactorialNegative() {
    472     for (int n : NEGATIVE_INTEGER_CANDIDATES) {
    473       try {
    474         IntMath.factorial(n);
    475         fail("Expected IllegalArgumentException");
    476       } catch (IllegalArgumentException expected) {}
    477     }
    478   }
    479 
    480   // Depends on the correctness of BigIntegerMath.binomial.
    481   @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
    482   public void testBinomial() {
    483     for (int n = 0; n <= 50; n++) {
    484       for (int k = 0; k <= n; k++) {
    485         BigInteger expectedBig = BigIntegerMath.binomial(n, k);
    486         int expectedInt = fitsInInt(expectedBig) ? expectedBig.intValue() : Integer.MAX_VALUE;
    487         assertEquals(expectedInt, IntMath.binomial(n, k));
    488       }
    489     }
    490   }
    491 
    492   @GwtIncompatible("binomial")
    493   public void testBinomialOutside() {
    494     for (int n = 0; n <= 50; n++) {
    495       try {
    496         IntMath.binomial(n, -1);
    497         fail("Expected IllegalArgumentException");
    498       } catch (IllegalArgumentException expected) {}
    499       try {
    500         IntMath.binomial(n, n + 1);
    501         fail("Expected IllegalArgumentException");
    502       } catch (IllegalArgumentException expected) {}
    503     }
    504   }
    505 
    506   @GwtIncompatible("binomial")
    507   public void testBinomialNegative() {
    508     for (int n : NEGATIVE_INTEGER_CANDIDATES) {
    509       try {
    510         IntMath.binomial(n, 0);
    511         fail("Expected IllegalArgumentException");
    512       } catch (IllegalArgumentException expected) {}
    513     }
    514   }
    515 
    516   @GwtIncompatible("java.math.BigInteger")
    517   public void testMean() {
    518     // Odd-sized ranges have an obvious mean
    519     assertMean(2, 1, 3);
    520 
    521     assertMean(-2, -3, -1);
    522     assertMean(0, -1, 1);
    523     assertMean(1, -1, 3);
    524     assertMean((1 << 30) - 1, -1, Integer.MAX_VALUE);
    525 
    526     // Even-sized ranges should prefer the lower mean
    527     assertMean(2, 1, 4);
    528     assertMean(-3, -4, -1);
    529     assertMean(0, -1, 2);
    530     assertMean(0, Integer.MIN_VALUE + 2, Integer.MAX_VALUE);
    531     assertMean(0, 0, 1);
    532     assertMean(-1, -1, 0);
    533     assertMean(-1, Integer.MIN_VALUE, Integer.MAX_VALUE);
    534 
    535     // x == y == mean
    536     assertMean(1, 1, 1);
    537     assertMean(0, 0, 0);
    538     assertMean(-1, -1, -1);
    539     assertMean(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
    540     assertMean(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
    541 
    542     // Exhaustive checks
    543     for (int x : ALL_INTEGER_CANDIDATES) {
    544       for (int y : ALL_INTEGER_CANDIDATES) {
    545         assertMean(x, y);
    546       }
    547     }
    548   }
    549 
    550   /**
    551    * Helper method that asserts the arithmetic mean of x and y is equal
    552    * to the expectedMean.
    553    */
    554   private static void assertMean(int expectedMean, int x, int y) {
    555     assertEquals("The expectedMean should be the same as computeMeanSafely",
    556         expectedMean, computeMeanSafely(x, y));
    557     assertMean(x, y);
    558   }
    559 
    560   /**
    561    * Helper method that asserts the arithmetic mean of x and y is equal
    562    * to the result of computeMeanSafely.
    563    */
    564   private static void assertMean(int x, int y) {
    565     int expectedMean = computeMeanSafely(x, y);
    566     assertEquals(expectedMean, IntMath.mean(x, y));
    567     assertEquals("The mean of x and y should equal the mean of y and x",
    568         expectedMean, IntMath.mean(y, x));
    569   }
    570 
    571   /**
    572    * Computes the mean in a way that is obvious and resilient to
    573    * overflow by using BigInteger arithmetic.
    574    */
    575   private static int computeMeanSafely(int x, int y) {
    576     BigInteger bigX = BigInteger.valueOf(x);
    577     BigInteger bigY = BigInteger.valueOf(y);
    578     BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
    579         .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
    580     // parseInt blows up on overflow as opposed to intValue() which does not.
    581     return Integer.parseInt(bigMean.toString());
    582   }
    583 
    584   private static boolean fitsInInt(BigInteger big) {
    585     return big.bitLength() <= 31;
    586   }
    587 
    588   @GwtIncompatible("NullPointerTester")
    589   public void testNullPointers() {
    590     NullPointerTester tester = new NullPointerTester();
    591     tester.setDefault(int.class, 1);
    592     tester.testAllPublicStaticMethods(IntMath.class);
    593   }
    594 
    595   private static int force32(int value) {
    596     // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
    597     return value & 0xffffffff;
    598   }
    599 }
    600