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