001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with this 004 * work for additional information regarding copyright ownership. The ASF 005 * licenses this file to You under the Apache License, Version 2.0 (the 006 * "License"); you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law 009 * or agreed to in writing, software distributed under the License is 010 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 011 * KIND, either express or implied. See the License for the specific language 012 * governing permissions and limitations under the License. 013 */ 014 package org.apache.commons.math.util; 015 016 import java.math.BigDecimal; 017 import java.math.BigInteger; 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.List; 021 import java.util.Map; 022 023 import junit.framework.Test; 024 import junit.framework.TestCase; 025 import junit.framework.TestSuite; 026 027 import org.apache.commons.math.random.RandomDataImpl; 028 import org.apache.commons.math.TestUtils; 029 030 /** 031 * Test cases for the MathUtils class. 032 * @version $Revision: 790243 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug 033 * 2007) $ 034 */ 035 public final class MathUtilsTest extends TestCase { 036 037 public MathUtilsTest(String name) { 038 super(name); 039 } 040 041 public static Test suite() { 042 TestSuite suite = new TestSuite(MathUtilsTest.class); 043 suite.setName("MathUtils Tests"); 044 return suite; 045 } 046 047 /** cached binomial coefficients */ 048 private static final List<Map<Integer, Long>> binomialCache = new ArrayList<Map<Integer, Long>>(); 049 050 /** 051 * Exact (caching) recursive implementation to test against 052 */ 053 private long binomialCoefficient(int n, int k) throws ArithmeticException { 054 if (binomialCache.size() > n) { 055 Long cachedResult = binomialCache.get(n).get(Integer.valueOf(k)); 056 if (cachedResult != null) { 057 return cachedResult.longValue(); 058 } 059 } 060 long result = -1; 061 if ((n == k) || (k == 0)) { 062 result = 1; 063 } else if ((k == 1) || (k == n - 1)) { 064 result = n; 065 } else { 066 // Reduce stack depth for larger values of n 067 if (k < n - 100) { 068 binomialCoefficient(n - 100, k); 069 } 070 if (k > 100) { 071 binomialCoefficient(n - 100, k - 100); 072 } 073 result = MathUtils.addAndCheck(binomialCoefficient(n - 1, k - 1), 074 binomialCoefficient(n - 1, k)); 075 } 076 if (result == -1) { 077 throw new ArithmeticException( 078 "error computing binomial coefficient"); 079 } 080 for (int i = binomialCache.size(); i < n + 1; i++) { 081 binomialCache.add(new HashMap<Integer, Long>()); 082 } 083 binomialCache.get(n).put(Integer.valueOf(k), Long.valueOf(result)); 084 return result; 085 } 086 087 /** 088 * Exact direct multiplication implementation to test against 089 */ 090 private long factorial(int n) { 091 long result = 1; 092 for (int i = 2; i <= n; i++) { 093 result *= i; 094 } 095 return result; 096 } 097 098 /** Verify that b(0,0) = 1 */ 099 public void test0Choose0() { 100 assertEquals(MathUtils.binomialCoefficientDouble(0, 0), 1d, 0); 101 assertEquals(MathUtils.binomialCoefficientLog(0, 0), 0d, 0); 102 assertEquals(MathUtils.binomialCoefficient(0, 0), 1); 103 } 104 105 public void testAddAndCheck() { 106 int big = Integer.MAX_VALUE; 107 int bigNeg = Integer.MIN_VALUE; 108 assertEquals(big, MathUtils.addAndCheck(big, 0)); 109 try { 110 MathUtils.addAndCheck(big, 1); 111 fail("Expecting ArithmeticException"); 112 } catch (ArithmeticException ex) { 113 } 114 try { 115 MathUtils.addAndCheck(bigNeg, -1); 116 fail("Expecting ArithmeticException"); 117 } catch (ArithmeticException ex) { 118 } 119 } 120 121 public void testAddAndCheckLong() { 122 long max = Long.MAX_VALUE; 123 long min = Long.MIN_VALUE; 124 assertEquals(max, MathUtils.addAndCheck(max, 0L)); 125 assertEquals(min, MathUtils.addAndCheck(min, 0L)); 126 assertEquals(max, MathUtils.addAndCheck(0L, max)); 127 assertEquals(min, MathUtils.addAndCheck(0L, min)); 128 assertEquals(1, MathUtils.addAndCheck(-1L, 2L)); 129 assertEquals(1, MathUtils.addAndCheck(2L, -1L)); 130 assertEquals(-3, MathUtils.addAndCheck(-2L, -1L)); 131 assertEquals(min, MathUtils.addAndCheck(min + 1, -1L)); 132 testAddAndCheckLongFailure(max, 1L); 133 testAddAndCheckLongFailure(min, -1L); 134 testAddAndCheckLongFailure(1L, max); 135 testAddAndCheckLongFailure(-1L, min); 136 } 137 138 private void testAddAndCheckLongFailure(long a, long b) { 139 try { 140 MathUtils.addAndCheck(a, b); 141 fail("Expecting ArithmeticException"); 142 } catch (ArithmeticException ex) { 143 // success 144 } 145 } 146 147 public void testBinomialCoefficient() { 148 long[] bcoef5 = { 149 1, 150 5, 151 10, 152 10, 153 5, 154 1 }; 155 long[] bcoef6 = { 156 1, 157 6, 158 15, 159 20, 160 15, 161 6, 162 1 }; 163 for (int i = 0; i < 6; i++) { 164 assertEquals("5 choose " + i, bcoef5[i], MathUtils.binomialCoefficient(5, i)); 165 } 166 for (int i = 0; i < 7; i++) { 167 assertEquals("6 choose " + i, bcoef6[i], MathUtils.binomialCoefficient(6, i)); 168 } 169 170 for (int n = 1; n < 10; n++) { 171 for (int k = 0; k <= n; k++) { 172 assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficient(n, k)); 173 assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE); 174 assertEquals(n + " choose " + k, Math.log(binomialCoefficient(n, k)), MathUtils.binomialCoefficientLog(n, k), 10E-12); 175 } 176 } 177 178 int[] n = { 34, 66, 100, 1500, 1500 }; 179 int[] k = { 17, 33, 10, 1500 - 4, 4 }; 180 for (int i = 0; i < n.length; i++) { 181 long expected = binomialCoefficient(n[i], k[i]); 182 assertEquals(n[i] + " choose " + k[i], expected, 183 MathUtils.binomialCoefficient(n[i], k[i])); 184 assertEquals(n[i] + " choose " + k[i], expected, 185 MathUtils.binomialCoefficientDouble(n[i], k[i]), 0.0); 186 assertEquals("log(" + n[i] + " choose " + k[i] + ")", Math.log(expected), 187 MathUtils.binomialCoefficientLog(n[i], k[i]), 0.0); 188 } 189 } 190 191 /** 192 * Tests correctness for large n and sharpness of upper bound in API doc 193 * JIRA: MATH-241 194 */ 195 public void testBinomialCoefficientLarge() throws Exception { 196 // This tests all legal and illegal values for n <= 200. 197 for (int n = 0; n <= 200; n++) { 198 for (int k = 0; k <= n; k++) { 199 long ourResult = -1; 200 long exactResult = -1; 201 boolean shouldThrow = false; 202 boolean didThrow = false; 203 try { 204 ourResult = MathUtils.binomialCoefficient(n, k); 205 } catch (ArithmeticException ex) { 206 didThrow = true; 207 } 208 try { 209 exactResult = binomialCoefficient(n, k); 210 } catch (ArithmeticException ex) { 211 shouldThrow = true; 212 } 213 assertEquals(n + " choose " + k, exactResult, ourResult); 214 assertEquals(n + " choose " + k, shouldThrow, didThrow); 215 assertTrue(n + " choose " + k, (n > 66 || !didThrow)); 216 217 if (!shouldThrow && exactResult > 1) { 218 assertEquals(n + " choose " + k, 1., 219 MathUtils.binomialCoefficientDouble(n, k) / exactResult, 1e-10); 220 assertEquals(n + " choose " + k, 1, 221 MathUtils.binomialCoefficientLog(n, k) / Math.log(exactResult), 1e-10); 222 } 223 } 224 } 225 226 long ourResult = MathUtils.binomialCoefficient(300, 3); 227 long exactResult = binomialCoefficient(300, 3); 228 assertEquals(exactResult, ourResult); 229 230 ourResult = MathUtils.binomialCoefficient(700, 697); 231 exactResult = binomialCoefficient(700, 697); 232 assertEquals(exactResult, ourResult); 233 234 // This one should throw 235 try { 236 MathUtils.binomialCoefficient(700, 300); 237 fail("Expecting ArithmeticException"); 238 } catch (ArithmeticException ex) { 239 // Expected 240 } 241 242 int n = 10000; 243 ourResult = MathUtils.binomialCoefficient(n, 3); 244 exactResult = binomialCoefficient(n, 3); 245 assertEquals(exactResult, ourResult); 246 assertEquals(1, MathUtils.binomialCoefficientDouble(n, 3) / exactResult, 1e-10); 247 assertEquals(1, MathUtils.binomialCoefficientLog(n, 3) / Math.log(exactResult), 1e-10); 248 249 } 250 251 public void testBinomialCoefficientFail() { 252 try { 253 MathUtils.binomialCoefficient(4, 5); 254 fail("expecting IllegalArgumentException"); 255 } catch (IllegalArgumentException ex) { 256 // ignored 257 } 258 259 try { 260 MathUtils.binomialCoefficientDouble(4, 5); 261 fail("expecting IllegalArgumentException"); 262 } catch (IllegalArgumentException ex) { 263 // ignored 264 } 265 266 try { 267 MathUtils.binomialCoefficientLog(4, 5); 268 fail("expecting IllegalArgumentException"); 269 } catch (IllegalArgumentException ex) { 270 // ignored 271 } 272 273 try { 274 MathUtils.binomialCoefficient(-1, -2); 275 fail("expecting IllegalArgumentException"); 276 } catch (IllegalArgumentException ex) { 277 // ignored 278 } 279 try { 280 MathUtils.binomialCoefficientDouble(-1, -2); 281 fail("expecting IllegalArgumentException"); 282 } catch (IllegalArgumentException ex) { 283 // ignored 284 } 285 try { 286 MathUtils.binomialCoefficientLog(-1, -2); 287 fail("expecting IllegalArgumentException"); 288 } catch (IllegalArgumentException ex) { 289 // ignored 290 } 291 292 try { 293 MathUtils.binomialCoefficient(67, 30); 294 fail("expecting ArithmeticException"); 295 } catch (ArithmeticException ex) { 296 // ignored 297 } 298 try { 299 MathUtils.binomialCoefficient(67, 34); 300 fail("expecting ArithmeticException"); 301 } catch (ArithmeticException ex) { 302 // ignored 303 } 304 double x = MathUtils.binomialCoefficientDouble(1030, 515); 305 assertTrue("expecting infinite binomial coefficient", Double 306 .isInfinite(x)); 307 } 308 309 public void testCompareTo() { 310 assertEquals(0, MathUtils.compareTo(152.33, 152.32, .011)); 311 assertTrue(MathUtils.compareTo(152.308, 152.32, .011) < 0); 312 assertTrue(MathUtils.compareTo(152.33, 152.318, .011) > 0); 313 } 314 315 public void testCosh() { 316 double x = 3.0; 317 double expected = 10.06766; 318 assertEquals(expected, MathUtils.cosh(x), 1.0e-5); 319 } 320 321 public void testCoshNaN() { 322 assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN))); 323 } 324 325 public void testEquals() { 326 double[] testArray = { 327 Double.NaN, 328 Double.POSITIVE_INFINITY, 329 Double.NEGATIVE_INFINITY, 330 1d, 331 0d }; 332 for (int i = 0; i < testArray.length; i++) { 333 for (int j = 0; j < testArray.length; j++) { 334 if (i == j) { 335 assertTrue(MathUtils.equals(testArray[i], testArray[j])); 336 assertTrue(MathUtils.equals(testArray[j], testArray[i])); 337 } else { 338 assertTrue(!MathUtils.equals(testArray[i], testArray[j])); 339 assertTrue(!MathUtils.equals(testArray[j], testArray[i])); 340 } 341 } 342 } 343 } 344 345 public void testEqualsWithAllowedDelta() { 346 assertTrue(MathUtils.equals(153.0000, 153.0000, .0625)); 347 assertTrue(MathUtils.equals(153.0000, 153.0625, .0625)); 348 assertTrue(MathUtils.equals(152.9375, 153.0000, .0625)); 349 assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1.0)); 350 assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); 351 assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0)); 352 assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); 353 assertFalse(MathUtils.equals(153.0000, 153.0625, .0624)); 354 assertFalse(MathUtils.equals(152.9374, 153.0000, .0625)); 355 } 356 357 public void testEqualsWithAllowedUlps() { 358 assertTrue(MathUtils.equals(153, 153, 1)); 359 360 assertTrue(MathUtils.equals(153, 153.00000000000003, 1)); 361 assertFalse(MathUtils.equals(153, 153.00000000000006, 1)); 362 assertTrue(MathUtils.equals(153, 152.99999999999997, 1)); 363 assertFalse(MathUtils.equals(153, 152.99999999999994, 1)); 364 365 assertTrue(MathUtils.equals(-128, -127.99999999999999, 1)); 366 assertFalse(MathUtils.equals(-128, -127.99999999999997, 1)); 367 assertTrue(MathUtils.equals(-128, -128.00000000000003, 1)); 368 assertFalse(MathUtils.equals(-128, -128.00000000000006, 1)); 369 370 assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1)); 371 assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1)); 372 373 assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1)); 374 assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1)); 375 376 377 assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1)); 378 379 assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000)); 380 } 381 382 public void testArrayEquals() { 383 assertFalse(MathUtils.equals(new double[] { 1d }, null)); 384 assertFalse(MathUtils.equals(null, new double[] { 1d })); 385 assertTrue(MathUtils.equals((double[]) null, (double[]) null)); 386 387 assertFalse(MathUtils.equals(new double[] { 1d }, new double[0])); 388 assertTrue(MathUtils.equals(new double[] { 1d }, new double[] { 1d })); 389 assertTrue(MathUtils.equals(new double[] { 390 Double.NaN, Double.POSITIVE_INFINITY, 391 Double.NEGATIVE_INFINITY, 1d, 0d 392 }, new double[] { 393 Double.NaN, Double.POSITIVE_INFINITY, 394 Double.NEGATIVE_INFINITY, 1d, 0d 395 })); 396 assertFalse(MathUtils.equals(new double[] { Double.POSITIVE_INFINITY }, 397 new double[] { Double.NEGATIVE_INFINITY })); 398 assertFalse(MathUtils.equals(new double[] { 1d }, 399 new double[] { MathUtils.nextAfter(1d, 2d) })); 400 401 } 402 403 public void testFactorial() { 404 for (int i = 1; i < 21; i++) { 405 assertEquals(i + "! ", factorial(i), MathUtils.factorial(i)); 406 assertEquals(i + "! ", factorial(i), MathUtils.factorialDouble(i), Double.MIN_VALUE); 407 assertEquals(i + "! ", Math.log(factorial(i)), MathUtils.factorialLog(i), 10E-12); 408 } 409 410 assertEquals("0", 1, MathUtils.factorial(0)); 411 assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14); 412 assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14); 413 } 414 415 public void testFactorialFail() { 416 try { 417 MathUtils.factorial(-1); 418 fail("expecting IllegalArgumentException"); 419 } catch (IllegalArgumentException ex) { 420 // ignored 421 } 422 try { 423 MathUtils.factorialDouble(-1); 424 fail("expecting IllegalArgumentException"); 425 } catch (IllegalArgumentException ex) { 426 // ignored 427 } 428 try { 429 MathUtils.factorialLog(-1); 430 fail("expecting IllegalArgumentException"); 431 } catch (IllegalArgumentException ex) { 432 // ignored 433 } 434 try { 435 MathUtils.factorial(21); 436 fail("expecting ArithmeticException"); 437 } catch (ArithmeticException ex) { 438 // ignored 439 } 440 assertTrue("expecting infinite factorial value", Double.isInfinite(MathUtils.factorialDouble(171))); 441 } 442 443 public void testGcd() { 444 int a = 30; 445 int b = 50; 446 int c = 77; 447 448 assertEquals(0, MathUtils.gcd(0, 0)); 449 450 assertEquals(b, MathUtils.gcd(0, b)); 451 assertEquals(a, MathUtils.gcd(a, 0)); 452 assertEquals(b, MathUtils.gcd(0, -b)); 453 assertEquals(a, MathUtils.gcd(-a, 0)); 454 455 assertEquals(10, MathUtils.gcd(a, b)); 456 assertEquals(10, MathUtils.gcd(-a, b)); 457 assertEquals(10, MathUtils.gcd(a, -b)); 458 assertEquals(10, MathUtils.gcd(-a, -b)); 459 460 assertEquals(1, MathUtils.gcd(a, c)); 461 assertEquals(1, MathUtils.gcd(-a, c)); 462 assertEquals(1, MathUtils.gcd(a, -c)); 463 assertEquals(1, MathUtils.gcd(-a, -c)); 464 465 assertEquals(3 * (1<<15), MathUtils.gcd(3 * (1<<20), 9 * (1<<15))); 466 467 assertEquals(Integer.MAX_VALUE, MathUtils.gcd(Integer.MAX_VALUE, 0)); 468 assertEquals(Integer.MAX_VALUE, MathUtils.gcd(-Integer.MAX_VALUE, 0)); 469 assertEquals(1<<30, MathUtils.gcd(1<<30, -Integer.MIN_VALUE)); 470 try { 471 // gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE 472 MathUtils.gcd(Integer.MIN_VALUE, 0); 473 fail("expecting ArithmeticException"); 474 } catch (ArithmeticException expected) { 475 // expected 476 } 477 try { 478 // gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE 479 MathUtils.gcd(0, Integer.MIN_VALUE); 480 fail("expecting ArithmeticException"); 481 } catch (ArithmeticException expected) { 482 // expected 483 } 484 try { 485 // gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE 486 MathUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE); 487 fail("expecting ArithmeticException"); 488 } catch (ArithmeticException expected) { 489 // expected 490 } 491 } 492 493 public void testHash() { 494 double[] testArray = { 495 Double.NaN, 496 Double.POSITIVE_INFINITY, 497 Double.NEGATIVE_INFINITY, 498 1d, 499 0d, 500 1E-14, 501 (1 + 1E-14), 502 Double.MIN_VALUE, 503 Double.MAX_VALUE }; 504 for (int i = 0; i < testArray.length; i++) { 505 for (int j = 0; j < testArray.length; j++) { 506 if (i == j) { 507 assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j])); 508 assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i])); 509 } else { 510 assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j])); 511 assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i])); 512 } 513 } 514 } 515 } 516 517 public void testArrayHash() { 518 assertEquals(0, MathUtils.hash((double[]) null)); 519 assertEquals(MathUtils.hash(new double[] { 520 Double.NaN, Double.POSITIVE_INFINITY, 521 Double.NEGATIVE_INFINITY, 1d, 0d 522 }), 523 MathUtils.hash(new double[] { 524 Double.NaN, Double.POSITIVE_INFINITY, 525 Double.NEGATIVE_INFINITY, 1d, 0d 526 })); 527 assertFalse(MathUtils.hash(new double[] { 1d }) == 528 MathUtils.hash(new double[] { MathUtils.nextAfter(1d, 2d) })); 529 assertFalse(MathUtils.hash(new double[] { 1d }) == 530 MathUtils.hash(new double[] { 1d, 1d })); 531 } 532 533 /** 534 * Make sure that permuted arrays do not hash to the same value. 535 */ 536 public void testPermutedArrayHash() { 537 double[] original = new double[10]; 538 double[] permuted = new double[10]; 539 RandomDataImpl random = new RandomDataImpl(); 540 541 // Generate 10 distinct random values 542 for (int i = 0; i < 10; i++) { 543 original[i] = random.nextUniform(i + 0.5, i + 0.75); 544 } 545 546 // Generate a random permutation, making sure it is not the identity 547 boolean isIdentity = true; 548 do { 549 int[] permutation = random.nextPermutation(10, 10); 550 for (int i = 0; i < 10; i++) { 551 if (i != permutation[i]) { 552 isIdentity = false; 553 } 554 permuted[i] = original[permutation[i]]; 555 } 556 } while (isIdentity); 557 558 // Verify that permuted array has different hash 559 assertFalse(MathUtils.hash(original) == MathUtils.hash(permuted)); 560 } 561 562 public void testIndicatorByte() { 563 assertEquals((byte)1, MathUtils.indicator((byte)2)); 564 assertEquals((byte)1, MathUtils.indicator((byte)0)); 565 assertEquals((byte)(-1), MathUtils.indicator((byte)(-2))); 566 } 567 568 public void testIndicatorDouble() { 569 double delta = 0.0; 570 assertEquals(1.0, MathUtils.indicator(2.0), delta); 571 assertEquals(1.0, MathUtils.indicator(0.0), delta); 572 assertEquals(-1.0, MathUtils.indicator(-2.0), delta); 573 assertEquals(Double.NaN, MathUtils.indicator(Double.NaN)); 574 } 575 576 public void testIndicatorFloat() { 577 float delta = 0.0F; 578 assertEquals(1.0F, MathUtils.indicator(2.0F), delta); 579 assertEquals(1.0F, MathUtils.indicator(0.0F), delta); 580 assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta); 581 } 582 583 public void testIndicatorInt() { 584 assertEquals(1, MathUtils.indicator((2))); 585 assertEquals(1, MathUtils.indicator((0))); 586 assertEquals((-1), MathUtils.indicator((-2))); 587 } 588 589 public void testIndicatorLong() { 590 assertEquals(1L, MathUtils.indicator(2L)); 591 assertEquals(1L, MathUtils.indicator(0L)); 592 assertEquals(-1L, MathUtils.indicator(-2L)); 593 } 594 595 public void testIndicatorShort() { 596 assertEquals((short)1, MathUtils.indicator((short)2)); 597 assertEquals((short)1, MathUtils.indicator((short)0)); 598 assertEquals((short)(-1), MathUtils.indicator((short)(-2))); 599 } 600 601 public void testLcm() { 602 int a = 30; 603 int b = 50; 604 int c = 77; 605 606 assertEquals(0, MathUtils.lcm(0, b)); 607 assertEquals(0, MathUtils.lcm(a, 0)); 608 assertEquals(b, MathUtils.lcm(1, b)); 609 assertEquals(a, MathUtils.lcm(a, 1)); 610 assertEquals(150, MathUtils.lcm(a, b)); 611 assertEquals(150, MathUtils.lcm(-a, b)); 612 assertEquals(150, MathUtils.lcm(a, -b)); 613 assertEquals(150, MathUtils.lcm(-a, -b)); 614 assertEquals(2310, MathUtils.lcm(a, c)); 615 616 // Assert that no intermediate value overflows: 617 // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b) 618 assertEquals((1<<20)*15, MathUtils.lcm((1<<20)*3, (1<<20)*5)); 619 620 // Special case 621 assertEquals(0, MathUtils.lcm(0, 0)); 622 623 try { 624 // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int 625 MathUtils.lcm(Integer.MIN_VALUE, 1); 626 fail("Expecting ArithmeticException"); 627 } catch (ArithmeticException ex) { 628 // expected 629 } 630 631 try { 632 // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int 633 MathUtils.lcm(Integer.MIN_VALUE, 1<<20); 634 fail("Expecting ArithmeticException"); 635 } catch (ArithmeticException ex) { 636 // expected 637 } 638 639 try { 640 MathUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1); 641 fail("Expecting ArithmeticException"); 642 } catch (ArithmeticException ex) { 643 // expected 644 } 645 } 646 647 public void testLog() { 648 assertEquals(2.0, MathUtils.log(2, 4), 0); 649 assertEquals(3.0, MathUtils.log(2, 8), 0); 650 assertTrue(Double.isNaN(MathUtils.log(-1, 1))); 651 assertTrue(Double.isNaN(MathUtils.log(1, -1))); 652 assertTrue(Double.isNaN(MathUtils.log(0, 0))); 653 assertEquals(0, MathUtils.log(0, 10), 0); 654 assertEquals(Double.NEGATIVE_INFINITY, MathUtils.log(10, 0), 0); 655 } 656 657 public void testMulAndCheck() { 658 int big = Integer.MAX_VALUE; 659 int bigNeg = Integer.MIN_VALUE; 660 assertEquals(big, MathUtils.mulAndCheck(big, 1)); 661 try { 662 MathUtils.mulAndCheck(big, 2); 663 fail("Expecting ArithmeticException"); 664 } catch (ArithmeticException ex) { 665 } 666 try { 667 MathUtils.mulAndCheck(bigNeg, 2); 668 fail("Expecting ArithmeticException"); 669 } catch (ArithmeticException ex) { 670 } 671 } 672 673 public void testMulAndCheckLong() { 674 long max = Long.MAX_VALUE; 675 long min = Long.MIN_VALUE; 676 assertEquals(max, MathUtils.mulAndCheck(max, 1L)); 677 assertEquals(min, MathUtils.mulAndCheck(min, 1L)); 678 assertEquals(0L, MathUtils.mulAndCheck(max, 0L)); 679 assertEquals(0L, MathUtils.mulAndCheck(min, 0L)); 680 assertEquals(max, MathUtils.mulAndCheck(1L, max)); 681 assertEquals(min, MathUtils.mulAndCheck(1L, min)); 682 assertEquals(0L, MathUtils.mulAndCheck(0L, max)); 683 assertEquals(0L, MathUtils.mulAndCheck(0L, min)); 684 assertEquals(1L, MathUtils.mulAndCheck(-1L, -1L)); 685 assertEquals(min, MathUtils.mulAndCheck(min / 2, 2)); 686 testMulAndCheckLongFailure(max, 2L); 687 testMulAndCheckLongFailure(2L, max); 688 testMulAndCheckLongFailure(min, 2L); 689 testMulAndCheckLongFailure(2L, min); 690 testMulAndCheckLongFailure(min, -1L); 691 testMulAndCheckLongFailure(-1L, min); 692 } 693 694 private void testMulAndCheckLongFailure(long a, long b) { 695 try { 696 MathUtils.mulAndCheck(a, b); 697 fail("Expecting ArithmeticException"); 698 } catch (ArithmeticException ex) { 699 // success 700 } 701 } 702 703 public void testNextAfter() { 704 // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000 705 assertEquals(16.0, MathUtils.nextAfter(15.999999999999998, 34.27555555555555), 0.0); 706 707 // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe 708 assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 34.27555555555555), 0.0); 709 710 // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe 711 assertEquals(15.999999999999996, MathUtils.nextAfter(15.999999999999998, 2.142222222222222), 0.0); 712 713 // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe 714 assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 2.142222222222222), 0.0); 715 716 // 0x4020000000000000 0x404123456789abcd -> 4020000000000001 717 assertEquals(8.000000000000002, MathUtils.nextAfter(8.0, 34.27555555555555), 0.0); 718 719 // 0xc020000000000000 0x404123456789abcd -> c01fffffffffffff 720 assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 34.27555555555555), 0.0); 721 722 // 0x4020000000000000 0x400123456789abcd -> 401fffffffffffff 723 assertEquals(7.999999999999999, MathUtils.nextAfter(8.0, 2.142222222222222), 0.0); 724 725 // 0xc020000000000000 0x400123456789abcd -> c01fffffffffffff 726 assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 2.142222222222222), 0.0); 727 728 // 0x3f2e43753d36a223 0x3f2e43753d36a224 -> 3f2e43753d36a224 729 assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.308922399667661E-4), 0.0); 730 731 // 0x3f2e43753d36a223 0x3f2e43753d36a223 -> 3f2e43753d36a224 732 assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); 733 734 // 0x3f2e43753d36a223 0x3f2e43753d36a222 -> 3f2e43753d36a222 735 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); 736 737 // 0x3f2e43753d36a223 0xbf2e43753d36a224 -> 3f2e43753d36a222 738 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.308922399667661E-4), 0.0); 739 740 // 0x3f2e43753d36a223 0xbf2e43753d36a223 -> 3f2e43753d36a222 741 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); 742 743 // 0x3f2e43753d36a223 0xbf2e43753d36a222 -> 3f2e43753d36a222 744 assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); 745 746 // 0xbf2e43753d36a223 0x3f2e43753d36a224 -> bf2e43753d36a222 747 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.308922399667661E-4), 0.0); 748 749 // 0xbf2e43753d36a223 0x3f2e43753d36a223 -> bf2e43753d36a222 750 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676606E-4), 0.0); 751 752 // 0xbf2e43753d36a223 0x3f2e43753d36a222 -> bf2e43753d36a222 753 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676603E-4), 0.0); 754 755 // 0xbf2e43753d36a223 0xbf2e43753d36a224 -> bf2e43753d36a224 756 assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.308922399667661E-4), 0.0); 757 758 // 0xbf2e43753d36a223 0xbf2e43753d36a223 -> bf2e43753d36a224 759 assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676606E-4), 0.0); 760 761 // 0xbf2e43753d36a223 0xbf2e43753d36a222 -> bf2e43753d36a222 762 assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676603E-4), 0.0); 763 764 } 765 766 public void testNextAfterSpecialCases() { 767 assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0))); 768 assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0))); 769 assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0))); 770 assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY))); 771 assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY))); 772 assertEquals(Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0); 773 assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0); 774 assertEquals(0, MathUtils.nextAfter(Double.MIN_VALUE, -1), 0); 775 assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0); 776 } 777 778 public void testScalb() { 779 assertEquals( 0.0, MathUtils.scalb(0.0, 5), 1.0e-15); 780 assertEquals(32.0, MathUtils.scalb(1.0, 5), 1.0e-15); 781 assertEquals(1.0 / 32.0, MathUtils.scalb(1.0, -5), 1.0e-15); 782 assertEquals(Math.PI, MathUtils.scalb(Math.PI, 0), 1.0e-15); 783 assertTrue(Double.isInfinite(MathUtils.scalb(Double.POSITIVE_INFINITY, 1))); 784 assertTrue(Double.isInfinite(MathUtils.scalb(Double.NEGATIVE_INFINITY, 1))); 785 assertTrue(Double.isNaN(MathUtils.scalb(Double.NaN, 1))); 786 } 787 788 public void testNormalizeAngle() { 789 for (double a = -15.0; a <= 15.0; a += 0.1) { 790 for (double b = -15.0; b <= 15.0; b += 0.2) { 791 double c = MathUtils.normalizeAngle(a, b); 792 assertTrue((b - Math.PI) <= c); 793 assertTrue(c <= (b + Math.PI)); 794 double twoK = Math.rint((a - c) / Math.PI); 795 assertEquals(c, a - twoK * Math.PI, 1.0e-14); 796 } 797 } 798 } 799 800 public void testRoundDouble() { 801 double x = 1.234567890; 802 assertEquals(1.23, MathUtils.round(x, 2), 0.0); 803 assertEquals(1.235, MathUtils.round(x, 3), 0.0); 804 assertEquals(1.2346, MathUtils.round(x, 4), 0.0); 805 806 // JIRA MATH-151 807 assertEquals(39.25, MathUtils.round(39.245, 2), 0.0); 808 assertEquals(39.24, MathUtils.round(39.245, 2, BigDecimal.ROUND_DOWN), 0.0); 809 double xx = 39.0; 810 xx = xx + 245d / 1000d; 811 assertEquals(39.25, MathUtils.round(xx, 2), 0.0); 812 813 // BZ 35904 814 assertEquals(30.1d, MathUtils.round(30.095d, 2), 0.0d); 815 assertEquals(30.1d, MathUtils.round(30.095d, 1), 0.0d); 816 assertEquals(33.1d, MathUtils.round(33.095d, 1), 0.0d); 817 assertEquals(33.1d, MathUtils.round(33.095d, 2), 0.0d); 818 assertEquals(50.09d, MathUtils.round(50.085d, 2), 0.0d); 819 assertEquals(50.19d, MathUtils.round(50.185d, 2), 0.0d); 820 assertEquals(50.01d, MathUtils.round(50.005d, 2), 0.0d); 821 assertEquals(30.01d, MathUtils.round(30.005d, 2), 0.0d); 822 assertEquals(30.65d, MathUtils.round(30.645d, 2), 0.0d); 823 824 assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0); 825 assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0); 826 assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0); 827 assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0); 828 assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0); 829 assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0); 830 831 assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0); 832 assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0); 833 assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0); 834 assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0); 835 assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0); 836 assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0); 837 838 assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0); 839 assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0); 840 assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0); 841 assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0); 842 assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0); 843 assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0); 844 845 assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); 846 assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 847 assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); 848 assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); 849 assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 850 assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); 851 assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 852 assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 853 854 assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); 855 assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 856 assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); 857 assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); 858 assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 859 assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); 860 assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 861 assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 862 assertEquals(1.236, MathUtils.round(1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 863 assertEquals(-1.236, MathUtils.round(-1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 864 865 assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0); 866 assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0); 867 assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0); 868 assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0); 869 assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0); 870 assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0); 871 assertEquals(1.235, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0); 872 assertEquals(-1.235, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0); 873 874 assertEquals(-1.23, MathUtils.round(-1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); 875 assertEquals(1.23, MathUtils.round(1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); 876 877 try { 878 MathUtils.round(1.234, 2, BigDecimal.ROUND_UNNECESSARY); 879 fail(); 880 } catch (ArithmeticException ex) { 881 // success 882 } 883 884 assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0); 885 assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0); 886 assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0); 887 assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0); 888 assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0); 889 assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0); 890 891 try { 892 MathUtils.round(1.234, 2, 1923); 893 fail(); 894 } catch (IllegalArgumentException ex) { 895 // success 896 } 897 898 // MATH-151 899 assertEquals(39.25, MathUtils.round(39.245, 2, BigDecimal.ROUND_HALF_UP), 0.0); 900 901 // special values 902 TestUtils.assertEquals(Double.NaN, MathUtils.round(Double.NaN, 2), 0.0); 903 assertEquals(0.0, MathUtils.round(0.0, 2), 0.0); 904 assertEquals(Double.POSITIVE_INFINITY, MathUtils.round(Double.POSITIVE_INFINITY, 2), 0.0); 905 assertEquals(Double.NEGATIVE_INFINITY, MathUtils.round(Double.NEGATIVE_INFINITY, 2), 0.0); 906 } 907 908 public void testRoundFloat() { 909 float x = 1.234567890f; 910 assertEquals(1.23f, MathUtils.round(x, 2), 0.0); 911 assertEquals(1.235f, MathUtils.round(x, 3), 0.0); 912 assertEquals(1.2346f, MathUtils.round(x, 4), 0.0); 913 914 // BZ 35904 915 assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f); 916 assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f); 917 assertEquals(50.09f, MathUtils.round(50.085f, 2), 0.0f); 918 assertEquals(50.19f, MathUtils.round(50.185f, 2), 0.0f); 919 assertEquals(50.01f, MathUtils.round(50.005f, 2), 0.0f); 920 assertEquals(30.01f, MathUtils.round(30.005f, 2), 0.0f); 921 assertEquals(30.65f, MathUtils.round(30.645f, 2), 0.0f); 922 923 assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0); 924 assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0); 925 assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0); 926 assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0); 927 assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0); 928 assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0); 929 930 assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0); 931 assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0); 932 assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0); 933 assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0); 934 assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0); 935 assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0); 936 937 assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0); 938 assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0); 939 assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0); 940 assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0); 941 assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0); 942 assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0); 943 944 assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); 945 assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 946 assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); 947 assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0); 948 assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 949 assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0); 950 assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 951 assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0); 952 953 assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); 954 assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 955 assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); 956 assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0); 957 assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 958 assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0); 959 assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 960 assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 961 assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 962 assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0); 963 964 assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0); 965 assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0); 966 assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0); 967 assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0); 968 assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0); 969 assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0); 970 assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0); 971 assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0); 972 973 assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); 974 assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0); 975 976 try { 977 MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY); 978 fail(); 979 } catch (ArithmeticException ex) { 980 // success 981 } 982 983 assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0); 984 assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0); 985 assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0); 986 assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0); 987 assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0); 988 assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0); 989 990 try { 991 MathUtils.round(1.234f, 2, 1923); 992 fail(); 993 } catch (IllegalArgumentException ex) { 994 // success 995 } 996 997 // special values 998 TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f); 999 assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f); 1000 assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f); 1001 assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f); 1002 } 1003 1004 public void testSignByte() { 1005 assertEquals((byte) 1, MathUtils.sign((byte) 2)); 1006 assertEquals((byte) 0, MathUtils.sign((byte) 0)); 1007 assertEquals((byte) (-1), MathUtils.sign((byte) (-2))); 1008 } 1009 1010 public void testSignDouble() { 1011 double delta = 0.0; 1012 assertEquals(1.0, MathUtils.sign(2.0), delta); 1013 assertEquals(0.0, MathUtils.sign(0.0), delta); 1014 assertEquals(-1.0, MathUtils.sign(-2.0), delta); 1015 TestUtils.assertSame(-0. / 0., MathUtils.sign(Double.NaN)); 1016 } 1017 1018 public void testSignFloat() { 1019 float delta = 0.0F; 1020 assertEquals(1.0F, MathUtils.sign(2.0F), delta); 1021 assertEquals(0.0F, MathUtils.sign(0.0F), delta); 1022 assertEquals(-1.0F, MathUtils.sign(-2.0F), delta); 1023 TestUtils.assertSame(Float.NaN, MathUtils.sign(Float.NaN)); 1024 } 1025 1026 public void testSignInt() { 1027 assertEquals(1, MathUtils.sign(2)); 1028 assertEquals(0, MathUtils.sign(0)); 1029 assertEquals((-1), MathUtils.sign((-2))); 1030 } 1031 1032 public void testSignLong() { 1033 assertEquals(1L, MathUtils.sign(2L)); 1034 assertEquals(0L, MathUtils.sign(0L)); 1035 assertEquals(-1L, MathUtils.sign(-2L)); 1036 } 1037 1038 public void testSignShort() { 1039 assertEquals((short) 1, MathUtils.sign((short) 2)); 1040 assertEquals((short) 0, MathUtils.sign((short) 0)); 1041 assertEquals((short) (-1), MathUtils.sign((short) (-2))); 1042 } 1043 1044 public void testSinh() { 1045 double x = 3.0; 1046 double expected = 10.01787; 1047 assertEquals(expected, MathUtils.sinh(x), 1.0e-5); 1048 } 1049 1050 public void testSinhNaN() { 1051 assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN))); 1052 } 1053 1054 public void testSubAndCheck() { 1055 int big = Integer.MAX_VALUE; 1056 int bigNeg = Integer.MIN_VALUE; 1057 assertEquals(big, MathUtils.subAndCheck(big, 0)); 1058 assertEquals(bigNeg + 1, MathUtils.subAndCheck(bigNeg, -1)); 1059 assertEquals(-1, MathUtils.subAndCheck(bigNeg, -big)); 1060 try { 1061 MathUtils.subAndCheck(big, -1); 1062 fail("Expecting ArithmeticException"); 1063 } catch (ArithmeticException ex) { 1064 } 1065 try { 1066 MathUtils.subAndCheck(bigNeg, 1); 1067 fail("Expecting ArithmeticException"); 1068 } catch (ArithmeticException ex) { 1069 } 1070 } 1071 1072 public void testSubAndCheckErrorMessage() { 1073 int big = Integer.MAX_VALUE; 1074 try { 1075 MathUtils.subAndCheck(big, -1); 1076 fail("Expecting ArithmeticException"); 1077 } catch (ArithmeticException ex) { 1078 assertEquals("overflow: subtract", ex.getMessage()); 1079 } 1080 } 1081 1082 public void testSubAndCheckLong() { 1083 long max = Long.MAX_VALUE; 1084 long min = Long.MIN_VALUE; 1085 assertEquals(max, MathUtils.subAndCheck(max, 0)); 1086 assertEquals(min, MathUtils.subAndCheck(min, 0)); 1087 assertEquals(-max, MathUtils.subAndCheck(0, max)); 1088 assertEquals(min + 1, MathUtils.subAndCheck(min, -1)); 1089 // min == -1-max 1090 assertEquals(-1, MathUtils.subAndCheck(-max - 1, -max)); 1091 assertEquals(max, MathUtils.subAndCheck(-1, -1 - max)); 1092 testSubAndCheckLongFailure(0L, min); 1093 testSubAndCheckLongFailure(max, -1L); 1094 testSubAndCheckLongFailure(min, 1L); 1095 } 1096 1097 private void testSubAndCheckLongFailure(long a, long b) { 1098 try { 1099 MathUtils.subAndCheck(a, b); 1100 fail("Expecting ArithmeticException"); 1101 } catch (ArithmeticException ex) { 1102 // success 1103 } 1104 1105 } 1106 1107 public void testPow() { 1108 1109 assertEquals(1801088541, MathUtils.pow(21, 7)); 1110 assertEquals(1, MathUtils.pow(21, 0)); 1111 try { 1112 MathUtils.pow(21, -7); 1113 fail("Expecting IllegalArgumentException"); 1114 } catch (IllegalArgumentException e) { 1115 // expected behavior 1116 } 1117 1118 assertEquals(1801088541, MathUtils.pow(21, 7l)); 1119 assertEquals(1, MathUtils.pow(21, 0l)); 1120 try { 1121 MathUtils.pow(21, -7l); 1122 fail("Expecting IllegalArgumentException"); 1123 } catch (IllegalArgumentException e) { 1124 // expected behavior 1125 } 1126 1127 assertEquals(1801088541l, MathUtils.pow(21l, 7)); 1128 assertEquals(1l, MathUtils.pow(21l, 0)); 1129 try { 1130 MathUtils.pow(21l, -7); 1131 fail("Expecting IllegalArgumentException"); 1132 } catch (IllegalArgumentException e) { 1133 // expected behavior 1134 } 1135 1136 assertEquals(1801088541l, MathUtils.pow(21l, 7l)); 1137 assertEquals(1l, MathUtils.pow(21l, 0l)); 1138 try { 1139 MathUtils.pow(21l, -7l); 1140 fail("Expecting IllegalArgumentException"); 1141 } catch (IllegalArgumentException e) { 1142 // expected behavior 1143 } 1144 1145 BigInteger twentyOne = BigInteger.valueOf(21l); 1146 assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7)); 1147 assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0)); 1148 try { 1149 MathUtils.pow(twentyOne, -7); 1150 fail("Expecting IllegalArgumentException"); 1151 } catch (IllegalArgumentException e) { 1152 // expected behavior 1153 } 1154 1155 assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7l)); 1156 assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0l)); 1157 try { 1158 MathUtils.pow(twentyOne, -7l); 1159 fail("Expecting IllegalArgumentException"); 1160 } catch (IllegalArgumentException e) { 1161 // expected behavior 1162 } 1163 1164 assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, BigInteger.valueOf(7l))); 1165 assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, BigInteger.ZERO)); 1166 try { 1167 MathUtils.pow(twentyOne, BigInteger.valueOf(-7l)); 1168 fail("Expecting IllegalArgumentException"); 1169 } catch (IllegalArgumentException e) { 1170 // expected behavior 1171 } 1172 1173 BigInteger bigOne = 1174 new BigInteger("1543786922199448028351389769265814882661837148" + 1175 "4763915343722775611762713982220306372888519211" + 1176 "560905579993523402015636025177602059044911261"); 1177 assertEquals(bigOne, MathUtils.pow(twentyOne, 103)); 1178 assertEquals(bigOne, MathUtils.pow(twentyOne, 103l)); 1179 assertEquals(bigOne, MathUtils.pow(twentyOne, BigInteger.valueOf(103l))); 1180 1181 } 1182 1183 public void testL1DistanceDouble() { 1184 double[] p1 = { 2.5, 0.0 }; 1185 double[] p2 = { -0.5, 4.0 }; 1186 assertEquals(7.0, MathUtils.distance1(p1, p2)); 1187 } 1188 1189 public void testL1DistanceInt() { 1190 int[] p1 = { 3, 0 }; 1191 int[] p2 = { 0, 4 }; 1192 assertEquals(7, MathUtils.distance1(p1, p2)); 1193 } 1194 1195 public void testL2DistanceDouble() { 1196 double[] p1 = { 2.5, 0.0 }; 1197 double[] p2 = { -0.5, 4.0 }; 1198 assertEquals(5.0, MathUtils.distance(p1, p2)); 1199 } 1200 1201 public void testL2DistanceInt() { 1202 int[] p1 = { 3, 0 }; 1203 int[] p2 = { 0, 4 }; 1204 assertEquals(5.0, MathUtils.distance(p1, p2)); 1205 } 1206 1207 public void testLInfDistanceDouble() { 1208 double[] p1 = { 2.5, 0.0 }; 1209 double[] p2 = { -0.5, 4.0 }; 1210 assertEquals(4.0, MathUtils.distanceInf(p1, p2)); 1211 } 1212 1213 public void testLInfDistanceInt() { 1214 int[] p1 = { 3, 0 }; 1215 int[] p2 = { 0, 4 }; 1216 assertEquals(4, MathUtils.distanceInf(p1, p2)); 1217 } 1218 1219 }