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_DOUBLE_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.DOUBLE_CANDIDATES_EXCEPT_NAN;
     23 import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES;
     24 import static com.google.common.math.MathTesting.FRACTIONAL_DOUBLE_CANDIDATES;
     25 import static com.google.common.math.MathTesting.INFINITIES;
     26 import static com.google.common.math.MathTesting.INTEGRAL_DOUBLE_CANDIDATES;
     27 import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
     28 import static com.google.common.math.MathTesting.POSITIVE_FINITE_DOUBLE_CANDIDATES;
     29 import static java.math.RoundingMode.CEILING;
     30 import static java.math.RoundingMode.DOWN;
     31 import static java.math.RoundingMode.FLOOR;
     32 import static java.math.RoundingMode.UNNECESSARY;
     33 import static java.math.RoundingMode.UP;
     34 import static java.util.Arrays.asList;
     35 
     36 import com.google.common.annotations.GwtCompatible;
     37 import com.google.common.annotations.GwtIncompatible;
     38 import com.google.common.collect.ImmutableList;
     39 import com.google.common.collect.Iterables;
     40 import com.google.common.primitives.Doubles;
     41 import com.google.common.testing.NullPointerTester;
     42 
     43 import junit.framework.TestCase;
     44 
     45 import java.math.BigDecimal;
     46 import java.math.BigInteger;
     47 import java.math.RoundingMode;
     48 import java.util.Arrays;
     49 import java.util.List;
     50 
     51 /**
     52  * Tests for {@code DoubleMath}.
     53  *
     54  * @author Louis Wasserman
     55  */
     56 @GwtCompatible(emulated = true)
     57 public class DoubleMathTest extends TestCase {
     58 
     59   private static final BigDecimal MAX_INT_AS_BIG_DECIMAL = BigDecimal.valueOf(Integer.MAX_VALUE);
     60   private static final BigDecimal MIN_INT_AS_BIG_DECIMAL = BigDecimal.valueOf(Integer.MIN_VALUE);
     61 
     62   private static final BigDecimal MAX_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
     63   private static final BigDecimal MIN_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
     64 
     65   private static final double MIN_NORMAL = 2.2250738585072014E-308; // Doubles.MIN_NORMAL from 1.6
     66 
     67   public void testConstantsMaxFactorial() {
     68     BigInteger maxDoubleValue = BigDecimal.valueOf(Double.MAX_VALUE).toBigInteger();
     69     assertTrue(BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL).compareTo(maxDoubleValue) <= 0);
     70     assertTrue(
     71         BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL + 1).compareTo(maxDoubleValue) > 0);
     72   }
     73 
     74   public void testConstantsEverySixteenthFactorial() {
     75     for (int i = 0, n = 0; n <= DoubleMath.MAX_FACTORIAL; i++, n += 16) {
     76       assertEquals(
     77           BigIntegerMath.factorial(n).doubleValue(), DoubleMath.everySixteenthFactorial[i]);
     78     }
     79   }
     80 
     81   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
     82   public void testRoundIntegralDoubleToInt() {
     83     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
     84       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
     85         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
     86         boolean isInBounds = expected.compareTo(MAX_INT_AS_BIG_DECIMAL) <= 0
     87             & expected.compareTo(MIN_INT_AS_BIG_DECIMAL) >= 0;
     88 
     89         try {
     90           assertEquals(expected.intValue(), DoubleMath.roundToInt(d, mode));
     91           assertTrue(isInBounds);
     92         } catch (ArithmeticException e) {
     93           assertFalse(isInBounds);
     94         }
     95       }
     96     }
     97   }
     98 
     99   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
    100   public void testRoundFractionalDoubleToInt() {
    101     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    102       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    103         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
    104         boolean isInBounds = expected.compareTo(MAX_INT_AS_BIG_DECIMAL) <= 0
    105             & expected.compareTo(MIN_INT_AS_BIG_DECIMAL) >= 0;
    106 
    107         try {
    108           assertEquals(expected.intValue(), DoubleMath.roundToInt(d, mode));
    109           assertTrue(isInBounds);
    110         } catch (ArithmeticException e) {
    111           assertFalse(isInBounds);
    112         }
    113       }
    114     }
    115   }
    116 
    117   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
    118   public void testRoundExactIntegralDoubleToInt() {
    119     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    120       BigDecimal expected = new BigDecimal(d).setScale(0, UNNECESSARY);
    121       boolean isInBounds = expected.compareTo(MAX_INT_AS_BIG_DECIMAL) <= 0
    122           & expected.compareTo(MIN_INT_AS_BIG_DECIMAL) >= 0;
    123 
    124       try {
    125         assertEquals(expected.intValue(), DoubleMath.roundToInt(d, UNNECESSARY));
    126         assertTrue(isInBounds);
    127       } catch (ArithmeticException e) {
    128         assertFalse(isInBounds);
    129       }
    130     }
    131   }
    132 
    133   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
    134   public void testRoundExactFractionalDoubleToIntFails() {
    135     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    136       try {
    137         DoubleMath.roundToInt(d, UNNECESSARY);
    138         fail("Expected ArithmeticException");
    139       } catch (ArithmeticException expected) {}
    140     }
    141   }
    142 
    143   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
    144   public void testRoundNaNToIntAlwaysFails() {
    145     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    146       try {
    147         DoubleMath.roundToInt(Double.NaN, mode);
    148         fail("Expected ArithmeticException");
    149       } catch (ArithmeticException expected) {}
    150     }
    151   }
    152 
    153   @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)")
    154   public void testRoundInfiniteToIntAlwaysFails() {
    155     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    156       try {
    157         DoubleMath.roundToInt(Double.POSITIVE_INFINITY, mode);
    158         fail("Expected ArithmeticException");
    159       } catch (ArithmeticException expected) {}
    160       try {
    161         DoubleMath.roundToInt(Double.NEGATIVE_INFINITY, mode);
    162         fail("Expected ArithmeticException");
    163       } catch (ArithmeticException expected) {}
    164     }
    165   }
    166 
    167   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    168   public void testRoundIntegralDoubleToLong() {
    169     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    170       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    171         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
    172         boolean isInBounds = expected.compareTo(MAX_LONG_AS_BIG_DECIMAL) <= 0
    173             & expected.compareTo(MIN_LONG_AS_BIG_DECIMAL) >= 0;
    174 
    175         try {
    176           assertEquals(expected.longValue(), DoubleMath.roundToLong(d, mode));
    177           assertTrue(isInBounds);
    178         } catch (ArithmeticException e) {
    179           assertFalse(isInBounds);
    180         }
    181       }
    182     }
    183   }
    184 
    185   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    186   public void testRoundFractionalDoubleToLong() {
    187     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    188       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    189         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
    190         boolean isInBounds = expected.compareTo(MAX_LONG_AS_BIG_DECIMAL) <= 0
    191             & expected.compareTo(MIN_LONG_AS_BIG_DECIMAL) >= 0;
    192 
    193         try {
    194           assertEquals(expected.longValue(), DoubleMath.roundToLong(d, mode));
    195           assertTrue(isInBounds);
    196         } catch (ArithmeticException e) {
    197           assertFalse(isInBounds);
    198         }
    199       }
    200     }
    201   }
    202 
    203   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    204   public void testRoundExactIntegralDoubleToLong() {
    205     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    206       // every mode except UNNECESSARY
    207       BigDecimal expected = new BigDecimal(d).setScale(0, UNNECESSARY);
    208       boolean isInBounds = expected.compareTo(MAX_LONG_AS_BIG_DECIMAL) <= 0
    209           & expected.compareTo(MIN_LONG_AS_BIG_DECIMAL) >= 0;
    210 
    211       try {
    212         assertEquals(expected.longValue(), DoubleMath.roundToLong(d, UNNECESSARY));
    213         assertTrue(isInBounds);
    214       } catch (ArithmeticException e) {
    215         assertFalse(isInBounds);
    216       }
    217     }
    218   }
    219 
    220   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    221   public void testRoundExactFractionalDoubleToLongFails() {
    222     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    223       try {
    224         DoubleMath.roundToLong(d, UNNECESSARY);
    225         fail("Expected ArithmeticException");
    226       } catch (ArithmeticException expected) {}
    227     }
    228   }
    229 
    230   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    231   public void testRoundNaNToLongAlwaysFails() {
    232     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    233       try {
    234         DoubleMath.roundToLong(Double.NaN, mode);
    235         fail("Expected ArithmeticException");
    236       } catch (ArithmeticException expected) {}
    237     }
    238   }
    239 
    240   @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)")
    241   public void testRoundInfiniteToLongAlwaysFails() {
    242     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    243       try {
    244         DoubleMath.roundToLong(Double.POSITIVE_INFINITY, mode);
    245         fail("Expected ArithmeticException");
    246       } catch (ArithmeticException expected) {}
    247       try {
    248         DoubleMath.roundToLong(Double.NEGATIVE_INFINITY, mode);
    249         fail("Expected ArithmeticException");
    250       } catch (ArithmeticException expected) {}
    251     }
    252   }
    253 
    254   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    255   public void testRoundIntegralDoubleToBigInteger() {
    256     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    257       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    258         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
    259         assertEquals(expected.toBigInteger(), DoubleMath.roundToBigInteger(d, mode));
    260       }
    261     }
    262   }
    263 
    264   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    265   public void testRoundFractionalDoubleToBigInteger() {
    266     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    267       for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
    268         BigDecimal expected = new BigDecimal(d).setScale(0, mode);
    269         assertEquals(expected.toBigInteger(), DoubleMath.roundToBigInteger(d, mode));
    270       }
    271     }
    272   }
    273 
    274   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    275   public void testRoundExactIntegralDoubleToBigInteger() {
    276     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    277       BigDecimal expected = new BigDecimal(d).setScale(0, UNNECESSARY);
    278       assertEquals(expected.toBigInteger(), DoubleMath.roundToBigInteger(d, UNNECESSARY));
    279     }
    280   }
    281 
    282   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    283   public void testRoundExactFractionalDoubleToBigIntegerFails() {
    284     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    285       try {
    286         DoubleMath.roundToBigInteger(d, UNNECESSARY);
    287         fail("Expected ArithmeticException");
    288       } catch (ArithmeticException expected) {}
    289     }
    290   }
    291 
    292   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    293   public void testRoundNaNToBigIntegerAlwaysFails() {
    294     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    295       try {
    296         DoubleMath.roundToBigInteger(Double.NaN, mode);
    297         fail("Expected ArithmeticException");
    298       } catch (ArithmeticException expected) {}
    299     }
    300   }
    301 
    302   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    303   public void testRoundInfiniteToBigIntegerAlwaysFails() {
    304     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    305       try {
    306         DoubleMath.roundToBigInteger(Double.POSITIVE_INFINITY, mode);
    307         fail("Expected ArithmeticException");
    308       } catch (ArithmeticException expected) {}
    309       try {
    310         DoubleMath.roundToBigInteger(Double.NEGATIVE_INFINITY, mode);
    311         fail("Expected ArithmeticException");
    312       } catch (ArithmeticException expected) {}
    313     }
    314   }
    315 
    316   @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)")
    317   public void testRoundLog2Floor() {
    318     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    319       int log2 = DoubleMath.log2(d, FLOOR);
    320       assertTrue(StrictMath.pow(2.0, log2) <= d);
    321       assertTrue(StrictMath.pow(2.0, log2 + 1) > d);
    322     }
    323   }
    324 
    325   @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath")
    326   public void testRoundLog2Ceiling() {
    327     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    328       int log2 = DoubleMath.log2(d, CEILING);
    329       assertTrue(StrictMath.pow(2.0, log2) >= d);
    330       double z = StrictMath.pow(2.0, log2 - 1);
    331       assertTrue(z < d);
    332     }
    333   }
    334 
    335   @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath")
    336   public void testRoundLog2Down() {
    337     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    338       int log2 = DoubleMath.log2(d, DOWN);
    339       if (d >= 1.0) {
    340         assertTrue(log2 >= 0);
    341         assertTrue(StrictMath.pow(2.0, log2) <= d);
    342         assertTrue(StrictMath.pow(2.0, log2 + 1) > d);
    343       } else {
    344         assertTrue(log2 <= 0);
    345         assertTrue(StrictMath.pow(2.0, log2) >= d);
    346         assertTrue(StrictMath.pow(2.0, log2 - 1) < d);
    347       }
    348     }
    349   }
    350 
    351   @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath")
    352   public void testRoundLog2Up() {
    353     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    354       int log2 = DoubleMath.log2(d, UP);
    355       if (d >= 1.0) {
    356         assertTrue(log2 >= 0);
    357         assertTrue(StrictMath.pow(2.0, log2) >= d);
    358         assertTrue(StrictMath.pow(2.0, log2 - 1) < d);
    359       } else {
    360         assertTrue(log2 <= 0);
    361         assertTrue(StrictMath.pow(2.0, log2) <= d);
    362         assertTrue(StrictMath.pow(2.0, log2 + 1) > d);
    363       }
    364     }
    365   }
    366 
    367   @GwtIncompatible("DoubleMath.log2(double, RoundingMode)")
    368   public void testRoundLog2ThrowsOnZerosInfinitiesAndNaN() {
    369     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    370       for (double d :
    371           asList(0.0, -0.0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) {
    372         try {
    373           DoubleMath.log2(d, mode);
    374           fail("Expected IllegalArgumentException");
    375         } catch (IllegalArgumentException expected) {}
    376       }
    377     }
    378   }
    379 
    380   @GwtIncompatible("DoubleMath.log2(double, RoundingMode)")
    381   public void testRoundLog2ThrowsOnNegative() {
    382     for (RoundingMode mode : ALL_ROUNDING_MODES) {
    383       for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    384         try {
    385           DoubleMath.log2(-d, mode);
    386           fail("Expected IllegalArgumentException");
    387         } catch (IllegalArgumentException expected) {}
    388       }
    389     }
    390   }
    391 
    392   @GwtIncompatible("DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath")
    393   public void testIsPowerOfTwoYes() {
    394     for (int i = -1074; i <= 1023; i++) {
    395       assertTrue(DoubleMath.isPowerOfTwo(StrictMath.pow(2.0, i)));
    396     }
    397   }
    398 
    399   @GwtIncompatible("DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath")
    400   public void testIsPowerOfTwo() {
    401     for (double x : ALL_DOUBLE_CANDIDATES) {
    402       boolean expected = x > 0 && !Double.isInfinite(x) && !Double.isNaN(x)
    403           && StrictMath.pow(2.0, DoubleMath.log2(x, FLOOR)) == x;
    404       assertEquals(expected, DoubleMath.isPowerOfTwo(x));
    405     }
    406   }
    407 
    408   public void testLog2SemiMonotonic() {
    409     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    410       assertTrue(DoubleMath.log2(d + 0.01) >= DoubleMath.log2(d));
    411     }
    412   }
    413 
    414   public void testLog2Negative() {
    415     for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
    416       assertTrue(Double.isNaN(DoubleMath.log2(-d)));
    417     }
    418   }
    419 
    420   public void testLog2Zero() {
    421     assertEquals(Double.NEGATIVE_INFINITY, DoubleMath.log2(0.0));
    422     assertEquals(Double.NEGATIVE_INFINITY, DoubleMath.log2(-0.0));
    423   }
    424 
    425   public void testLog2NaNInfinity() {
    426     assertEquals(Double.POSITIVE_INFINITY, DoubleMath.log2(Double.POSITIVE_INFINITY));
    427     assertTrue(Double.isNaN(DoubleMath.log2(Double.NEGATIVE_INFINITY)));
    428     assertTrue(Double.isNaN(DoubleMath.log2(Double.NaN)));
    429   }
    430 
    431 
    432   @GwtIncompatible("DoubleMath.isMathematicalInteger")
    433   public void testIsMathematicalIntegerIntegral() {
    434     for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
    435       assertTrue(DoubleMath.isMathematicalInteger(d));
    436     }
    437   }
    438 
    439   @GwtIncompatible("DoubleMath.isMathematicalInteger")
    440   public void testIsMathematicalIntegerFractional() {
    441     for (double d : FRACTIONAL_DOUBLE_CANDIDATES) {
    442       assertFalse(DoubleMath.isMathematicalInteger(d));
    443     }
    444   }
    445 
    446   @GwtIncompatible("DoubleMath.isMathematicalInteger")
    447   public void testIsMathematicalIntegerNotFinite() {
    448     for (double d :
    449         Arrays.asList(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) {
    450       assertFalse(DoubleMath.isMathematicalInteger(d));
    451     }
    452   }
    453 
    454   @GwtIncompatible("Math.ulp")
    455   public void testFactorial() {
    456     for (int i = 0; i <= DoubleMath.MAX_FACTORIAL; i++) {
    457       double actual = BigIntegerMath.factorial(i).doubleValue();
    458       double result = DoubleMath.factorial(i);
    459       assertEquals(actual, result, Math.ulp(actual));
    460     }
    461   }
    462 
    463   public void testFactorialTooHigh() {
    464     assertEquals(Double.POSITIVE_INFINITY, DoubleMath.factorial(DoubleMath.MAX_FACTORIAL + 1));
    465     assertEquals(Double.POSITIVE_INFINITY, DoubleMath.factorial(DoubleMath.MAX_FACTORIAL + 20));
    466   }
    467 
    468   public void testFactorialNegative() {
    469     for (int n : NEGATIVE_INTEGER_CANDIDATES) {
    470       try {
    471         DoubleMath.factorial(n);
    472         fail("Expected IllegalArgumentException");
    473       } catch (IllegalArgumentException expected) {}
    474     }
    475   }
    476 
    477   private static final ImmutableList<Double> FINITE_TOLERANCE_CANDIDATES =
    478       ImmutableList.of(-0.0, 0.0, 1.0, 100.0, 10000.0, Double.MAX_VALUE);
    479 
    480   private static final Iterable<Double> TOLERANCE_CANDIDATES =
    481       Iterables.concat(FINITE_TOLERANCE_CANDIDATES, ImmutableList.of(Double.POSITIVE_INFINITY));
    482 
    483   private static final List<Double> BAD_TOLERANCE_CANDIDATES =
    484       Doubles.asList(-Double.MIN_VALUE, -MIN_NORMAL, -1, -20, Double.NaN,
    485           Double.NEGATIVE_INFINITY, -0.001);
    486 
    487   public void testFuzzyEqualsFinite() {
    488     for (double a : FINITE_DOUBLE_CANDIDATES) {
    489       for (double b : FINITE_DOUBLE_CANDIDATES) {
    490         for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
    491           assertEquals(
    492               Math.abs(a - b) <= tolerance,
    493               DoubleMath.fuzzyEquals(a, b, tolerance));
    494         }
    495       }
    496     }
    497   }
    498 
    499   public void testFuzzyInfiniteVersusFiniteWithFiniteTolerance() {
    500     for (double inf : INFINITIES) {
    501       for (double a : FINITE_DOUBLE_CANDIDATES) {
    502         for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
    503           assertFalse(DoubleMath.fuzzyEquals(a, inf, tolerance));
    504           assertFalse(DoubleMath.fuzzyEquals(inf, a, tolerance));
    505         }
    506       }
    507     }
    508   }
    509 
    510   public void testFuzzyInfiniteVersusInfiniteWithFiniteTolerance() {
    511     for (double inf : INFINITIES) {
    512       for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
    513         assertTrue(DoubleMath.fuzzyEquals(inf, inf, tolerance));
    514         assertFalse(DoubleMath.fuzzyEquals(inf, -inf, tolerance));
    515       }
    516     }
    517   }
    518 
    519   public void testFuzzyEqualsInfiniteTolerance() {
    520     for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
    521       for (double b : DOUBLE_CANDIDATES_EXCEPT_NAN) {
    522         assertTrue(DoubleMath.fuzzyEquals(a, b, Double.POSITIVE_INFINITY));
    523       }
    524     }
    525   }
    526 
    527   public void testFuzzyEqualsOneNaN() {
    528     for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
    529       for (double tolerance : TOLERANCE_CANDIDATES) {
    530         assertFalse(DoubleMath.fuzzyEquals(a, Double.NaN, tolerance));
    531         assertFalse(DoubleMath.fuzzyEquals(Double.NaN, a, tolerance));
    532       }
    533     }
    534   }
    535 
    536   public void testFuzzyEqualsTwoNaNs() {
    537     for (double tolerance : TOLERANCE_CANDIDATES) {
    538       assertTrue(DoubleMath.fuzzyEquals(Double.NaN, Double.NaN, tolerance));
    539     }
    540   }
    541 
    542   public void testFuzzyEqualsZeroTolerance() {
    543     // make sure we test -0 tolerance
    544     for (double zero : Doubles.asList(0.0, -0.0)) {
    545       for (double a : ALL_DOUBLE_CANDIDATES) {
    546         for (double b : ALL_DOUBLE_CANDIDATES) {
    547           assertEquals(a == b || (Double.isNaN(a) && Double.isNaN(b)),
    548               DoubleMath.fuzzyEquals(a, b, zero));
    549         }
    550       }
    551     }
    552   }
    553 
    554   public void testFuzzyEqualsBadTolerance() {
    555     for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
    556       try {
    557         DoubleMath.fuzzyEquals(1, 2, tolerance);
    558         fail("Expected IllegalArgumentException");
    559       } catch (IllegalArgumentException expected) {
    560         // success
    561       }
    562     }
    563   }
    564 
    565   public void testFuzzyCompare() {
    566     for (double a : ALL_DOUBLE_CANDIDATES) {
    567       for (double b : ALL_DOUBLE_CANDIDATES) {
    568         for (double tolerance : TOLERANCE_CANDIDATES) {
    569           int expected = DoubleMath.fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b);
    570           int actual = DoubleMath.fuzzyCompare(a, b, tolerance);
    571           assertEquals(Integer.signum(expected), Integer.signum(actual));
    572         }
    573       }
    574     }
    575   }
    576 
    577   public void testFuzzyCompareBadTolerance() {
    578     for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
    579       try {
    580         DoubleMath.fuzzyCompare(1, 2, tolerance);
    581         fail("Expected IllegalArgumentException");
    582       } catch (IllegalArgumentException expected) {
    583         // success
    584       }
    585     }
    586   }
    587 
    588   @GwtIncompatible("DoubleMath.mean")
    589   public void testMean_doubleVarargs() {
    590     assertEquals(-1.375, DoubleMath.mean(1.1, -2.2, 4.4, -8.8), 1.0e-10);
    591     assertEquals(1.1, DoubleMath.mean(1.1), 1.0e-10);
    592     try {
    593       DoubleMath.mean(Double.NaN);
    594       fail("Expected IllegalArgumentException");
    595     } catch (IllegalArgumentException expected) {
    596     }
    597     try {
    598       DoubleMath.mean(Double.POSITIVE_INFINITY);
    599       fail("Expected IllegalArgumentException");
    600     } catch (IllegalArgumentException expected) {
    601     }
    602   }
    603 
    604   @GwtIncompatible("DoubleMath.mean")
    605   public void testMean_intVarargs() {
    606     assertEquals(-13.75, DoubleMath.mean(11, -22, 44, -88), 1.0e-10);
    607     assertEquals(11.0, DoubleMath.mean(11), 1.0e-10);
    608   }
    609 
    610   @GwtIncompatible("DoubleMath.mean")
    611   public void testMean_longVarargs() {
    612     assertEquals(-13.75, DoubleMath.mean(11L, -22L, 44L, -88L), 1.0e-10);
    613     assertEquals(11.0, DoubleMath.mean(11L), 1.0e-10);
    614   }
    615 
    616   @GwtIncompatible("DoubleMath.mean")
    617   public void testMean_emptyVarargs() {
    618     try {
    619       DoubleMath.mean();
    620       fail("Expected IllegalArgumentException");
    621     } catch (IllegalArgumentException expected) {
    622     }
    623   }
    624 
    625   @GwtIncompatible("DoubleMath.mean")
    626   public void testMean_doubleIterable() {
    627     assertEquals(-1.375, DoubleMath.mean(ImmutableList.of(1.1, -2.2, 4.4, -8.8)), 1.0e-10);
    628     assertEquals(1.1, DoubleMath.mean(ImmutableList.of(1.1)), 1.0e-10);
    629     try {
    630       DoubleMath.mean(ImmutableList.<Double>of());
    631       fail("Expected IllegalArgumentException");
    632     } catch (IllegalArgumentException expected) {
    633     }
    634     try {
    635       DoubleMath.mean(ImmutableList.of(Double.NaN));
    636       fail("Expected IllegalArgumentException");
    637     } catch (IllegalArgumentException expected) {
    638     }
    639     try {
    640       DoubleMath.mean(ImmutableList.of(Double.POSITIVE_INFINITY));
    641       fail("Expected IllegalArgumentException");
    642     } catch (IllegalArgumentException expected) {
    643     }
    644   }
    645 
    646   @GwtIncompatible("DoubleMath.mean")
    647   public void testMean_intIterable() {
    648     assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11, -22, 44, -88)), 1.0e-10);
    649     assertEquals(11, DoubleMath.mean(ImmutableList.of(11)), 1.0e-10);
    650     try {
    651       DoubleMath.mean(ImmutableList.<Integer>of());
    652       fail("Expected IllegalArgumentException");
    653     } catch (IllegalArgumentException expected) {
    654     }
    655   }
    656 
    657   @GwtIncompatible("DoubleMath.mean")
    658   public void testMean_longIterable() {
    659     assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11L, -22L, 44L, -88L)), 1.0e-10);
    660     assertEquals(11, DoubleMath.mean(ImmutableList.of(11L)), 1.0e-10);
    661     try {
    662       DoubleMath.mean(ImmutableList.<Long>of());
    663       fail("Expected IllegalArgumentException");
    664     } catch (IllegalArgumentException expected) {
    665     }
    666   }
    667 
    668   @GwtIncompatible("DoubleMath.mean")
    669   public void testMean_intIterator() {
    670     assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11, -22, 44, -88).iterator()), 1.0e-10);
    671     assertEquals(11, DoubleMath.mean(ImmutableList.of(11).iterator()), 1.0e-10);
    672     try {
    673       DoubleMath.mean(ImmutableList.<Integer>of().iterator());
    674       fail("Expected IllegalArgumentException");
    675     } catch (IllegalArgumentException expected) {
    676     }
    677   }
    678 
    679   @GwtIncompatible("DoubleMath.mean")
    680   public void testMean_longIterator() {
    681     assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11L, -22L, 44L, -88L).iterator()),
    682         1.0e-10);
    683     assertEquals(11, DoubleMath.mean(ImmutableList.of(11L).iterator()), 1.0e-10);
    684     try {
    685       DoubleMath.mean(ImmutableList.<Long>of().iterator());
    686       fail("Expected IllegalArgumentException");
    687     } catch (IllegalArgumentException expected) {
    688     }
    689   }
    690 
    691   @GwtIncompatible("NullPointerTester")
    692   public void testNullPointers() {
    693     NullPointerTester tester = new NullPointerTester();
    694     tester.setDefault(double.class, 3.0);
    695     tester.testAllPublicStaticMethods(DoubleMath.class);
    696   }
    697 }
    698