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