1 16 17 package org.apache.commons.math.util; 18 19 import java.math.BigDecimal ; 20 21 26 public final class MathUtils { 27 28 29 private static final byte ZB = (byte) 0; 30 31 32 private static final byte NB = (byte) -1; 33 34 35 private static final byte PB = (byte) 1; 36 37 38 private static final short ZS = (short) 0; 39 40 41 private static final short NS = (short) -1; 42 43 44 private static final short PS = (short) 1; 45 46 49 private MathUtils() { 50 } 51 52 60 public static double round(double x, int scale) { 61 return round(x, scale, BigDecimal.ROUND_HALF_UP); 62 } 63 64 75 public static double round( 76 double x, int scale, int roundingMethod) 77 { 78 return (new BigDecimal (x).setScale(scale, roundingMethod)) 79 .doubleValue(); 80 } 81 82 90 public static float round(float x, int scale) { 91 return round(x, scale, BigDecimal.ROUND_HALF_UP); 92 } 93 94 105 public static float round(float x, int scale, int roundingMethod) { 106 return (new BigDecimal (x).setScale(scale, roundingMethod)).floatValue(); 107 } 108 109 122 public static double sign(final double x) { 123 if (Double.isNaN(x)) { 124 return Double.NaN; 125 } 126 return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; 127 } 128 129 141 public static float sign(final float x) { 142 if (Float.isNaN(x)) { 143 return Float.NaN; 144 } 145 return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; 146 } 147 148 159 public static byte sign(final byte x) { 160 return (x == ZB) ? ZB : (x > ZB) ? PB : NB; 161 } 162 163 175 public static short sign(final short x) { 176 return (x == ZS) ? ZS : (x > ZS) ? PS : NS; 177 } 178 179 190 public static int sign(final int x) { 191 return (x == 0) ? 0 : (x > 0) ? 1 : -1; 192 } 193 194 205 public static long sign(final long x) { 206 return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; 207 } 208 209 217 public static double indicator(final double x) { 218 if (Double.isNaN(x)) { 219 return Double.NaN; 220 } 221 return (x >= 0.0) ? 1.0 : -1.0; 222 } 223 224 232 public static float indicator(final float x) { 233 if (Float.isNaN(x)) { 234 return Float.NaN; 235 } 236 return (x >= 0.0F) ? 1.0F : -1.0F; 237 } 238 239 246 public static byte indicator(final byte x) { 247 return (x >= ZB) ? PB : NB; 248 } 249 250 257 public static short indicator(final short x) { 258 return (x >= ZS) ? PS : NS; 259 } 260 261 268 public static int indicator(final int x) { 269 return (x >= 0) ? 1 : -1; 270 } 271 272 279 public static long indicator(final long x) { 280 return (x >= 0L) ? 1L : -1L; 281 } 282 283 307 public static long binomialCoefficient(final int n, final int k) { 308 if (n < k) { 309 throw new IllegalArgumentException ( 310 "must have n >= k for binomial coefficient (n,k)"); 311 } 312 if (n < 0) { 313 throw new IllegalArgumentException ( 314 "must have n >= 0 for binomial coefficient (n,k)"); 315 } 316 if ((n == k) || (k == 0)) { 317 return 1; 318 } 319 if ((k == 1) || (k == n - 1)) { 320 return n; 321 } 322 323 long result = Math.round(binomialCoefficientDouble(n, k)); 324 if (result == Long.MAX_VALUE) { 325 throw new ArithmeticException ( 326 "result too large to represent in a long integer"); 327 } 328 return result; 329 } 330 331 352 public static double binomialCoefficientDouble(final int n, final int k) { 353 return Math.floor(Math.exp(binomialCoefficientLog(n, k)) + 0.5); 354 } 355 356 373 public static double binomialCoefficientLog(final int n, final int k) { 374 if (n < k) { 375 throw new IllegalArgumentException ( 376 "must have n >= k for binomial coefficient (n,k)"); 377 } 378 if (n < 0) { 379 throw new IllegalArgumentException ( 380 "must have n >= 0 for binomial coefficient (n,k)"); 381 } 382 if ((n == k) || (k == 0)) { 383 return 0; 384 } 385 if ((k == 1) || (k == n - 1)) { 386 return Math.log((double) n); 387 } 388 double logSum = 0; 389 390 for (int i = k + 1; i <= n; i++) { 392 logSum += Math.log((double) i); 393 } 394 395 for (int i = 2; i <= n - k; i++) { 397 logSum -= Math.log((double) i); 398 } 399 400 return logSum; 401 } 402 403 426 public static long factorial(final int n) { 427 long result = Math.round(factorialDouble(n)); 428 if (result == Long.MAX_VALUE) { 429 throw new ArithmeticException ( 430 "result too large to represent in a long integer"); 431 } 432 return result; 433 } 434 435 456 public static double factorialDouble(final int n) { 457 if (n < 0) { 458 throw new IllegalArgumentException ("must have n >= 0 for n!"); 459 } 460 return Math.floor(Math.exp(factorialLog(n)) + 0.5); 461 } 462 463 475 public static double factorialLog(final int n) { 476 if (n < 0) { 477 throw new IllegalArgumentException ("must have n > 0 for n!"); 478 } 479 double logSum = 0; 480 for (int i = 2; i <= n; i++) { 481 logSum += Math.log((double) i); 482 } 483 return logSum; 484 } 485 486 493 public static double cosh(double x) { 494 return (Math.exp(x) + Math.exp(-x)) / 2.0; 495 } 496 497 504 public static double sinh(double x) { 505 return (Math.exp(x) - Math.exp(-x)) / 2.0; 506 } 507 508 514 public static int hash(double value) { 515 long bits = Double.doubleToLongBits(value); 516 return (int)(bits ^ (bits >>> 32)); 517 } 518 519 527 public static boolean equals(double x, double y) { 528 return ((Double.isNaN(x) && Double.isNaN(y)) || x == y); 529 } 530 531 540 public static int lcm(int a, int b) { 541 return Math.abs(mulAndCheck(a / gcd(a, b) , b)); 542 } 543 544 555 public static int gcd(int u, int v) { 556 if (u * v == 0) { 557 return (Math.abs(u) + Math.abs(v)); 558 } 559 564 if (u>0) { u=-u; } if (v>0) { v=-v; } int k=0; 568 while ((u&1)==0 && (v&1)==0 && k<31) { u/=2; v/=2; k++; } 571 if (k==31) { 572 throw new ArithmeticException ("overflow: gcd is 2^31"); 573 } 574 int t = ((u&1)==1) ? v : -(u/2); 577 do { 580 581 while ((t&1)==0) { t/=2; } 585 if (t>0) { 587 u = -t; 588 } else { 589 v = t; 590 } 591 t = (v - u)/2; 593 } while (t!=0); 596 return -u*(1<<k); } 598 599 609 public static int mulAndCheck(int x, int y) { 610 long m = ((long)x)*((long)y); 611 if (m < Integer.MIN_VALUE || 612 m > Integer.MAX_VALUE) { 613 throw new ArithmeticException ("overflow: mul"); 614 } 615 return (int)m; 616 } 617 618 628 public static int addAndCheck(int x, int y) { 629 long s = (long)x+(long)y; 630 if (s < Integer.MIN_VALUE || 631 s > Integer.MAX_VALUE) { 632 throw new ArithmeticException ("overflow: add"); 633 } 634 return (int)s; 635 } 636 637 647 public static int subAndCheck(int x, int y) { 648 long s = (long)x-(long)y; 649 if (s < Integer.MIN_VALUE || 650 s > Integer.MAX_VALUE) { 651 throw new ArithmeticException ("overflow: add"); 652 } 653 return (int)s; 654 } 655 } 656 | Popular Tags |