1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.math.util; 19 20 import java.math.BigDecimal; 21 22 /** 23 * Some useful additions to the built-in functions in {@link Math}. 24 * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $ 25 */ 26 public final class MathUtils { 27 28 /** -1.0 cast as a byte. */ 29 private static final byte NB = (byte)-1; 30 31 /** -1.0 cast as a short. */ 32 private static final short NS = (short)-1; 33 34 /** 1.0 cast as a byte. */ 35 private static final byte PB = (byte)1; 36 37 /** 1.0 cast as a short. */ 38 private static final short PS = (short)1; 39 40 /** 0.0 cast as a byte. */ 41 private static final byte ZB = (byte)0; 42 43 /** 0.0 cast as a short. */ 44 private static final short ZS = (short)0; 45 46 /** 2 π. */ 47 private static final double TWO_PI = 2 * Math.PI; 48 49 /** 50 * Private Constructor 51 */ 52 private MathUtils() { 53 super(); 54 } 55 56 /** 57 * Add two integers, checking for overflow. 58 * 59 * @param x an addend 60 * @param y an addend 61 * @return the sum <code>x+y</code> 62 * @throws ArithmeticException if the result can not be represented as an 63 * int 64 * @since 1.1 65 */ 66 public static int addAndCheck(int x, int y) { 67 long s = (long)x + (long)y; 68 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { 69 throw new ArithmeticException("overflow: add"); 70 } 71 return (int)s; 72 } 73 74 /** 75 * Add two long integers, checking for overflow. 76 * 77 * @param a an addend 78 * @param b an addend 79 * @return the sum <code>a+b</code> 80 * @throws ArithmeticException if the result can not be represented as an 81 * long 82 * @since 1.2 83 */ 84 public static long addAndCheck(long a, long b) { 85 return addAndCheck(a, b, "overflow: add"); 86 } 87 88 /** 89 * Add two long integers, checking for overflow. 90 * 91 * @param a an addend 92 * @param b an addend 93 * @param msg the message to use for any thrown exception. 94 * @return the sum <code>a+b</code> 95 * @throws ArithmeticException if the result can not be represented as an 96 * long 97 * @since 1.2 98 */ 99 private static long addAndCheck(long a, long b, String msg) { 100 long ret; 101 if (a > b) { 102 // use symmetry to reduce boundry cases 103 ret = addAndCheck(b, a, msg); 104 } else { 105 // assert a <= b 106 107 if (a < 0) { 108 if (b < 0) { 109 // check for negative overflow 110 if (Long.MIN_VALUE - b <= a) { 111 ret = a + b; 112 } else { 113 throw new ArithmeticException(msg); 114 } 115 } else { 116 // oppisite sign addition is always safe 117 ret = a + b; 118 } 119 } else { 120 // assert a >= 0 121 // assert b >= 0 122 123 // check for positive overflow 124 if (a <= Long.MAX_VALUE - b) { 125 ret = a + b; 126 } else { 127 throw new ArithmeticException(msg); 128 } 129 } 130 } 131 return ret; 132 } 133 134 /** 135 * Returns an exact representation of the <a 136 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 137 * Coefficient</a>, "<code>n choose k</code>", the number of 138 * <code>k</code>-element subsets that can be selected from an 139 * <code>n</code>-element set. 140 * <p> 141 * <Strong>Preconditions</strong>: 142 * <ul> 143 * <li> <code>0 <= k <= n </code> (otherwise 144 * <code>IllegalArgumentException</code> is thrown)</li> 145 * <li> The result is small enough to fit into a <code>long</code>. The 146 * largest value of <code>n</code> for which all coefficients are 147 * <code> < Long.MAX_VALUE</code> is 66. If the computed value exceeds 148 * <code>Long.MAX_VALUE</code> an <code>ArithMeticException 149 * </code> is 150 * thrown.</li> 151 * </ul></p> 152 * 153 * @param n the size of the set 154 * @param k the size of the subsets to be counted 155 * @return <code>n choose k</code> 156 * @throws IllegalArgumentException if preconditions are not met. 157 * @throws ArithmeticException if the result is too large to be represented 158 * by a long integer. 159 */ 160 public static long binomialCoefficient(final int n, final int k) { 161 if (n < k) { 162 throw new IllegalArgumentException( 163 "must have n >= k for binomial coefficient (n,k)"); 164 } 165 if (n < 0) { 166 throw new IllegalArgumentException( 167 "must have n >= 0 for binomial coefficient (n,k)"); 168 } 169 if ((n == k) || (k == 0)) { 170 return 1; 171 } 172 if ((k == 1) || (k == n - 1)) { 173 return n; 174 } 175 176 long result = Math.round(binomialCoefficientDouble(n, k)); 177 if (result == Long.MAX_VALUE) { 178 throw new ArithmeticException( 179 "result too large to represent in a long integer"); 180 } 181 return result; 182 } 183 184 /** 185 * Returns a <code>double</code> representation of the <a 186 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 187 * Coefficient</a>, "<code>n choose k</code>", the number of 188 * <code>k</code>-element subsets that can be selected from an 189 * <code>n</code>-element set. 190 * <p> 191 * <Strong>Preconditions</strong>: 192 * <ul> 193 * <li> <code>0 <= k <= n </code> (otherwise 194 * <code>IllegalArgumentException</code> is thrown)</li> 195 * <li> The result is small enough to fit into a <code>double</code>. The 196 * largest value of <code>n</code> for which all coefficients are < 197 * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE, 198 * Double.POSITIVE_INFINITY is returned</li> 199 * </ul></p> 200 * 201 * @param n the size of the set 202 * @param k the size of the subsets to be counted 203 * @return <code>n choose k</code> 204 * @throws IllegalArgumentException if preconditions are not met. 205 */ 206 public static double binomialCoefficientDouble(final int n, final int k) { 207 return Math.floor(Math.exp(binomialCoefficientLog(n, k)) + 0.5); 208 } 209 210 /** 211 * Returns the natural <code>log</code> of the <a 212 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 213 * Coefficient</a>, "<code>n choose k</code>", the number of 214 * <code>k</code>-element subsets that can be selected from an 215 * <code>n</code>-element set. 216 * <p> 217 * <Strong>Preconditions</strong>: 218 * <ul> 219 * <li> <code>0 <= k <= n </code> (otherwise 220 * <code>IllegalArgumentException</code> is thrown)</li> 221 * </ul></p> 222 * 223 * @param n the size of the set 224 * @param k the size of the subsets to be counted 225 * @return <code>n choose k</code> 226 * @throws IllegalArgumentException if preconditions are not met. 227 */ 228 public static double binomialCoefficientLog(final int n, final int k) { 229 if (n < k) { 230 throw new IllegalArgumentException( 231 "must have n >= k for binomial coefficient (n,k)"); 232 } 233 if (n < 0) { 234 throw new IllegalArgumentException( 235 "must have n >= 0 for binomial coefficient (n,k)"); 236 } 237 if ((n == k) || (k == 0)) { 238 return 0; 239 } 240 if ((k == 1) || (k == n - 1)) { 241 return Math.log((double)n); 242 } 243 double logSum = 0; 244 245 // n!/k! 246 for (int i = k + 1; i <= n; i++) { 247 logSum += Math.log((double)i); 248 } 249 250 // divide by (n-k)! 251 for (int i = 2; i <= n - k; i++) { 252 logSum -= Math.log((double)i); 253 } 254 255 return logSum; 256 } 257 258 /** 259 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html"> 260 * hyperbolic cosine</a> of x. 261 * 262 * @param x double value for which to find the hyperbolic cosine 263 * @return hyperbolic cosine of x 264 */ 265 public static double cosh(double x) { 266 return (Math.exp(x) + Math.exp(-x)) / 2.0; 267 } 268 269 /** 270 * Returns true iff both arguments are NaN or neither is NaN and they are 271 * equal 272 * 273 * @param x first value 274 * @param y second value 275 * @return true if the values are equal or both are NaN 276 */ 277 public static boolean equals(double x, double y) { 278 return ((Double.isNaN(x) && Double.isNaN(y)) || x == y); 279 } 280 281 /** 282 * Returns true iff both arguments are null or have same dimensions 283 * and all their elements are {@link #equals(double,double) equals} 284 * 285 * @param x first array 286 * @param y second array 287 * @return true if the values are both null or have same dimension 288 * and equal elements 289 * @since 1.2 290 */ 291 public static boolean equals(double[] x, double[] y) { 292 if ((x == null) || (y == null)) { 293 return !((x == null) ^ (y == null)); 294 } 295 if (x.length != y.length) { 296 return false; 297 } 298 for (int i = 0; i < x.length; ++i) { 299 if (!equals(x[i], y[i])) { 300 return false; 301 } 302 } 303 return true; 304 } 305 306 /** 307 * Returns n!. Shorthand for <code>n</code> <a 308 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the 309 * product of the numbers <code>1,...,n</code>. 310 * <p> 311 * <Strong>Preconditions</strong>: 312 * <ul> 313 * <li> <code>n >= 0</code> (otherwise 314 * <code>IllegalArgumentException</code> is thrown)</li> 315 * <li> The result is small enough to fit into a <code>long</code>. The 316 * largest value of <code>n</code> for which <code>n!</code> < 317 * Long.MAX_VALUE</code> is 20. If the computed value exceeds <code>Long.MAX_VALUE</code> 318 * an <code>ArithMeticException </code> is thrown.</li> 319 * </ul> 320 * </p> 321 * 322 * @param n argument 323 * @return <code>n!</code> 324 * @throws ArithmeticException if the result is too large to be represented 325 * by a long integer. 326 * @throws IllegalArgumentException if n < 0 327 */ 328 public static long factorial(final int n) { 329 long result = Math.round(factorialDouble(n)); 330 if (result == Long.MAX_VALUE) { 331 throw new ArithmeticException( 332 "result too large to represent in a long integer"); 333 } 334 return result; 335 } 336 337 /** 338 * Returns n!. Shorthand for <code>n</code> <a 339 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the 340 * product of the numbers <code>1,...,n</code> as a <code>double</code>. 341 * <p> 342 * <Strong>Preconditions</strong>: 343 * <ul> 344 * <li> <code>n >= 0</code> (otherwise 345 * <code>IllegalArgumentException</code> is thrown)</li> 346 * <li> The result is small enough to fit into a <code>double</code>. The 347 * largest value of <code>n</code> for which <code>n!</code> < 348 * Double.MAX_VALUE</code> is 170. If the computed value exceeds 349 * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li> 350 * </ul> 351 * </p> 352 * 353 * @param n argument 354 * @return <code>n!</code> 355 * @throws IllegalArgumentException if n < 0 356 */ 357 public static double factorialDouble(final int n) { 358 if (n < 0) { 359 throw new IllegalArgumentException("must have n >= 0 for n!"); 360 } 361 return Math.floor(Math.exp(factorialLog(n)) + 0.5); 362 } 363 364 /** 365 * Returns the natural logarithm of n!. 366 * <p> 367 * <Strong>Preconditions</strong>: 368 * <ul> 369 * <li> <code>n >= 0</code> (otherwise 370 * <code>IllegalArgumentException</code> is thrown)</li> 371 * </ul></p> 372 * 373 * @param n argument 374 * @return <code>n!</code> 375 * @throws IllegalArgumentException if preconditions are not met. 376 */ 377 public static double factorialLog(final int n) { 378 if (n < 0) { 379 throw new IllegalArgumentException("must have n > 0 for n!"); 380 } 381 double logSum = 0; 382 for (int i = 2; i <= n; i++) { 383 logSum += Math.log((double)i); 384 } 385 return logSum; 386 } 387 388 /** 389 * <p> 390 * Gets the greatest common divisor of the absolute value of two numbers, 391 * using the "binary gcd" method which avoids division and modulo 392 * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef 393 * Stein (1961). 394 * </p> 395 * 396 * @param u a non-zero number 397 * @param v a non-zero number 398 * @return the greatest common divisor, never zero 399 * @since 1.1 400 */ 401 public static int gcd(int u, int v) { 402 if (u * v == 0) { 403 return (Math.abs(u) + Math.abs(v)); 404 } 405 // keep u and v negative, as negative integers range down to 406 // -2^31, while positive numbers can only be as large as 2^31-1 407 // (i.e. we can't necessarily negate a negative number without 408 // overflow) 409 /* assert u!=0 && v!=0; */ 410 if (u > 0) { 411 u = -u; 412 } // make u negative 413 if (v > 0) { 414 v = -v; 415 } // make v negative 416 // B1. [Find power of 2] 417 int k = 0; 418 while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are 419 // both even... 420 u /= 2; 421 v /= 2; 422 k++; // cast out twos. 423 } 424 if (k == 31) { 425 throw new ArithmeticException("overflow: gcd is 2^31"); 426 } 427 // B2. Initialize: u and v have been divided by 2^k and at least 428 // one is odd. 429 int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; 430 // t negative: u was odd, v may be even (t replaces v) 431 // t positive: u was even, v is odd (t replaces u) 432 do { 433 /* assert u<0 && v<0; */ 434 // B4/B3: cast out twos from t. 435 while ((t & 1) == 0) { // while t is even.. 436 t /= 2; // cast out twos 437 } 438 // B5 [reset max(u,v)] 439 if (t > 0) { 440 u = -t; 441 } else { 442 v = t; 443 } 444 // B6/B3. at this point both u and v should be odd. 445 t = (v - u) / 2; 446 // |u| larger: t positive (replace u) 447 // |v| larger: t negative (replace v) 448 } while (t != 0); 449 return -u * (1 << k); // gcd is u*2^k 450 } 451 452 /** 453 * Returns an integer hash code representing the given double value. 454 * 455 * @param value the value to be hashed 456 * @return the hash code 457 */ 458 public static int hash(double value) { 459 long bits = Double.doubleToLongBits(value); 460 return (int)(bits ^ (bits >>> 32)); 461 } 462 463 /** 464 * Returns an integer hash code representing the given double array value. 465 * 466 * @param value the value to be hashed (may be null) 467 * @return the hash code 468 * @since 1.2 469 */ 470 public static int hash(double[] value) { 471 if (value == null) { 472 return 0; 473 } 474 int result = value.length; 475 for (int i = 0; i < value.length; ++i) { 476 result = result * 31 + hash(value[i]); 477 } 478 return result; 479 } 480 481 /** 482 * For a byte value x, this method returns (byte)(+1) if x >= 0 and 483 * (byte)(-1) if x < 0. 484 * 485 * @param x the value, a byte 486 * @return (byte)(+1) or (byte)(-1), depending on the sign of x 487 */ 488 public static byte indicator(final byte x) { 489 return (x >= ZB) ? PB : NB; 490 } 491 492 /** 493 * For a double precision value x, this method returns +1.0 if x >= 0 and 494 * -1.0 if x < 0. Returns <code>NaN</code> if <code>x</code> is 495 * <code>NaN</code>. 496 * 497 * @param x the value, a double 498 * @return +1.0 or -1.0, depending on the sign of x 499 */ 500 public static double indicator(final double x) { 501 if (Double.isNaN(x)) { 502 return Double.NaN; 503 } 504 return (x >= 0.0) ? 1.0 : -1.0; 505 } 506 507 /** 508 * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x < 509 * 0. Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>. 510 * 511 * @param x the value, a float 512 * @return +1.0F or -1.0F, depending on the sign of x 513 */ 514 public static float indicator(final float x) { 515 if (Float.isNaN(x)) { 516 return Float.NaN; 517 } 518 return (x >= 0.0F) ? 1.0F : -1.0F; 519 } 520 521 /** 522 * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0. 523 * 524 * @param x the value, an int 525 * @return +1 or -1, depending on the sign of x 526 */ 527 public static int indicator(final int x) { 528 return (x >= 0) ? 1 : -1; 529 } 530 531 /** 532 * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0. 533 * 534 * @param x the value, a long 535 * @return +1L or -1L, depending on the sign of x 536 */ 537 public static long indicator(final long x) { 538 return (x >= 0L) ? 1L : -1L; 539 } 540 541 /** 542 * For a short value x, this method returns (short)(+1) if x >= 0 and 543 * (short)(-1) if x < 0. 544 * 545 * @param x the value, a short 546 * @return (short)(+1) or (short)(-1), depending on the sign of x 547 */ 548 public static short indicator(final short x) { 549 return (x >= ZS) ? PS : NS; 550 } 551 552 /** 553 * Returns the least common multiple between two integer values. 554 * 555 * @param a the first integer value. 556 * @param b the second integer value. 557 * @return the least common multiple between a and b. 558 * @throws ArithmeticException if the lcm is too large to store as an int 559 * @since 1.1 560 */ 561 public static int lcm(int a, int b) { 562 return Math.abs(mulAndCheck(a / gcd(a, b), b)); 563 } 564 565 /** 566 * <p>Returns the 567 * <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a> 568 * for base <code>b</code> of <code>x</code>. 569 * </p> 570 * <p>Returns <code>NaN<code> if either argument is negative. If 571 * <code>base</code> is 0 and <code>x</code> is positive, 0 is returned. 572 * If <code>base</code> is positive and <code>x</code> is 0, 573 * <code>Double.NEGATIVE_INFINITY</code> is returned. If both arguments 574 * are 0, the result is <code>NaN</code>.</p> 575 * 576 * @param base the base of the logarithm, must be greater than 0 577 * @param x argument, must be greater than 0 578 * @return the value of the logarithm - the number y such that base^y = x. 579 * @since 1.2 580 */ 581 public static double log(double base, double x) { 582 return Math.log(x)/Math.log(base); 583 } 584 585 /** 586 * Multiply two integers, checking for overflow. 587 * 588 * @param x a factor 589 * @param y a factor 590 * @return the product <code>x*y</code> 591 * @throws ArithmeticException if the result can not be represented as an 592 * int 593 * @since 1.1 594 */ 595 public static int mulAndCheck(int x, int y) { 596 long m = ((long)x) * ((long)y); 597 if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) { 598 throw new ArithmeticException("overflow: mul"); 599 } 600 return (int)m; 601 } 602 603 /** 604 * Multiply two long integers, checking for overflow. 605 * 606 * @param a first value 607 * @param b second value 608 * @return the product <code>a * b</code> 609 * @throws ArithmeticException if the result can not be represented as an 610 * long 611 * @since 1.2 612 */ 613 public static long mulAndCheck(long a, long b) { 614 long ret; 615 String msg = "overflow: multiply"; 616 if (a > b) { 617 // use symmetry to reduce boundry cases 618 ret = mulAndCheck(b, a); 619 } else { 620 if (a < 0) { 621 if (b < 0) { 622 // check for positive overflow with negative a, negative b 623 if (a >= Long.MAX_VALUE / b) { 624 ret = a * b; 625 } else { 626 throw new ArithmeticException(msg); 627 } 628 } else if (b > 0) { 629 // check for negative overflow with negative a, positive b 630 if (Long.MIN_VALUE / b <= a) { 631 ret = a * b; 632 } else { 633 throw new ArithmeticException(msg); 634 635 } 636 } else { 637 // assert b == 0 638 ret = 0; 639 } 640 } else if (a > 0) { 641 // assert a > 0 642 // assert b > 0 643 644 // check for positive overflow with positive a, positive b 645 if (a <= Long.MAX_VALUE / b) { 646 ret = a * b; 647 } else { 648 throw new ArithmeticException(msg); 649 } 650 } else { 651 // assert a == 0 652 ret = 0; 653 } 654 } 655 return ret; 656 } 657 658 /** 659 * Get the next machine representable number after a number, moving 660 * in the direction of another number. 661 * <p> 662 * If <code>direction</code> is greater than or equal to<code>d</code>, 663 * the smallest machine representable number strictly greater than 664 * <code>d</code> is returned; otherwise the largest representable number 665 * strictly less than <code>d</code> is returned.</p> 666 * <p> 667 * If <code>d</code> is NaN or Infinite, it is returned unchanged.</p> 668 * 669 * @param d base number 670 * @param direction (the only important thing is whether 671 * direction is greater or smaller than d) 672 * @return the next machine representable number in the specified direction 673 * @since 1.2 674 */ 675 public static double nextAfter(double d, double direction) { 676 677 // handling of some important special cases 678 if (Double.isNaN(d) || Double.isInfinite(d)) { 679 return d; 680 } else if (d == 0) { 681 return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; 682 } 683 // special cases MAX_VALUE to infinity and MIN_VALUE to 0 684 // are handled just as normal numbers 685 686 // split the double in raw components 687 long bits = Double.doubleToLongBits(d); 688 long sign = bits & 0x8000000000000000L; 689 long exponent = bits & 0x7ff0000000000000L; 690 long mantissa = bits & 0x000fffffffffffffL; 691 692 if (d * (direction - d) >= 0) { 693 // we should increase the mantissa 694 if (mantissa == 0x000fffffffffffffL) { 695 return Double.longBitsToDouble(sign | 696 (exponent + 0x0010000000000000L)); 697 } else { 698 return Double.longBitsToDouble(sign | 699 exponent | (mantissa + 1)); 700 } 701 } else { 702 // we should decrease the mantissa 703 if (mantissa == 0L) { 704 return Double.longBitsToDouble(sign | 705 (exponent - 0x0010000000000000L) | 706 0x000fffffffffffffL); 707 } else { 708 return Double.longBitsToDouble(sign | 709 exponent | (mantissa - 1)); 710 } 711 } 712 713 } 714 715 /** 716 * Normalize an angle in a 2&pi wide interval around a center value. 717 * <p>This method has three main uses:</p> 718 * <ul> 719 * <li>normalize an angle between 0 and 2π:<br/> 720 * <code>a = MathUtils.normalizeAngle(a, Math.PI);</code></li> 721 * <li>normalize an angle between -π and +π<br/> 722 * <code>a = MathUtils.normalizeAngle(a, 0.0);</code></li> 723 * <li>compute the angle between two defining angular positions:<br> 724 * <code>angle = MathUtils.normalizeAngle(end, start) - start;</code></li> 725 * </ul> 726 * <p>Note that due to numerical accuracy and since π cannot be represented 727 * exactly, the result interval is <em>closed</em>, it cannot be half-closed 728 * as would be more satisfactory in a purely mathematical view.</p> 729 * @param a angle to normalize 730 * @param center center of the desired 2π interval for the result 731 * @return a-2kπ with integer k and center-π <= a-2kπ <= center+π 732 * @since 1.2 733 */ 734 public static double normalizeAngle(double a, double center) { 735 return a - TWO_PI * Math.floor((a + Math.PI - center) / TWO_PI); 736 } 737 738 /** 739 * Round the given value to the specified number of decimal places. The 740 * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. 741 * 742 * @param x the value to round. 743 * @param scale the number of digits to the right of the decimal point. 744 * @return the rounded value. 745 * @since 1.1 746 */ 747 public static double round(double x, int scale) { 748 return round(x, scale, BigDecimal.ROUND_HALF_UP); 749 } 750 751 /** 752 * Round the given value to the specified number of decimal places. The 753 * value is rounded using the given method which is any method defined in 754 * {@link BigDecimal}. 755 * 756 * @param x the value to round. 757 * @param scale the number of digits to the right of the decimal point. 758 * @param roundingMethod the rounding method as defined in 759 * {@link BigDecimal}. 760 * @return the rounded value. 761 * @since 1.1 762 */ 763 public static double round(double x, int scale, int roundingMethod) { 764 try { 765 return (new BigDecimal 766 (Double.toString(x)) 767 .setScale(scale, roundingMethod)) 768 .doubleValue(); 769 } catch (NumberFormatException ex) { 770 if (Double.isInfinite(x)) { 771 return x; 772 } else { 773 return Double.NaN; 774 } 775 } 776 } 777 778 /** 779 * Round the given value to the specified number of decimal places. The 780 * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method. 781 * 782 * @param x the value to round. 783 * @param scale the number of digits to the right of the decimal point. 784 * @return the rounded value. 785 * @since 1.1 786 */ 787 public static float round(float x, int scale) { 788 return round(x, scale, BigDecimal.ROUND_HALF_UP); 789 } 790 791 /** 792 * Round the given value to the specified number of decimal places. The 793 * value is rounded using the given method which is any method defined in 794 * {@link BigDecimal}. 795 * 796 * @param x the value to round. 797 * @param scale the number of digits to the right of the decimal point. 798 * @param roundingMethod the rounding method as defined in 799 * {@link BigDecimal}. 800 * @return the rounded value. 801 * @since 1.1 802 */ 803 public static float round(float x, int scale, int roundingMethod) { 804 float sign = indicator(x); 805 float factor = (float)Math.pow(10.0f, scale) * sign; 806 return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor; 807 } 808 809 /** 810 * Round the given non-negative, value to the "nearest" integer. Nearest is 811 * determined by the rounding method specified. Rounding methods are defined 812 * in {@link BigDecimal}. 813 * 814 * @param unscaled the value to round. 815 * @param sign the sign of the original, scaled value. 816 * @param roundingMethod the rounding method as defined in 817 * {@link BigDecimal}. 818 * @return the rounded value. 819 * @since 1.1 820 */ 821 private static double roundUnscaled(double unscaled, double sign, 822 int roundingMethod) { 823 switch (roundingMethod) { 824 case BigDecimal.ROUND_CEILING : 825 if (sign == -1) { 826 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); 827 } else { 828 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); 829 } 830 break; 831 case BigDecimal.ROUND_DOWN : 832 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); 833 break; 834 case BigDecimal.ROUND_FLOOR : 835 if (sign == -1) { 836 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); 837 } else { 838 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); 839 } 840 break; 841 case BigDecimal.ROUND_HALF_DOWN : { 842 unscaled = nextAfter(unscaled, Double.NEGATIVE_INFINITY); 843 double fraction = unscaled - Math.floor(unscaled); 844 if (fraction > 0.5) { 845 unscaled = Math.ceil(unscaled); 846 } else { 847 unscaled = Math.floor(unscaled); 848 } 849 break; 850 } 851 case BigDecimal.ROUND_HALF_EVEN : { 852 double fraction = unscaled - Math.floor(unscaled); 853 if (fraction > 0.5) { 854 unscaled = Math.ceil(unscaled); 855 } else if (fraction < 0.5) { 856 unscaled = Math.floor(unscaled); 857 } else { 858 // The following equality test is intentional and needed for rounding purposes 859 if (Math.floor(unscaled) / 2.0 == Math.floor(Math 860 .floor(unscaled) / 2.0)) { // even 861 unscaled = Math.floor(unscaled); 862 } else { // odd 863 unscaled = Math.ceil(unscaled); 864 } 865 } 866 break; 867 } 868 case BigDecimal.ROUND_HALF_UP : { 869 unscaled = nextAfter(unscaled, Double.POSITIVE_INFINITY); 870 double fraction = unscaled - Math.floor(unscaled); 871 if (fraction >= 0.5) { 872 unscaled = Math.ceil(unscaled); 873 } else { 874 unscaled = Math.floor(unscaled); 875 } 876 break; 877 } 878 case BigDecimal.ROUND_UNNECESSARY : 879 if (unscaled != Math.floor(unscaled)) { 880 throw new ArithmeticException("Inexact result from rounding"); 881 } 882 break; 883 case BigDecimal.ROUND_UP : 884 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); 885 break; 886 default : 887 throw new IllegalArgumentException("Invalid rounding method."); 888 } 889 return unscaled; 890 } 891 892 /** 893 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 894 * for byte value <code>x</code>. 895 * <p> 896 * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if 897 * x = 0, and (byte)(-1) if x < 0.</p> 898 * 899 * @param x the value, a byte 900 * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x 901 */ 902 public static byte sign(final byte x) { 903 return (x == ZB) ? ZB : (x > ZB) ? PB : NB; 904 } 905 906 /** 907 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 908 * for double precision <code>x</code>. 909 * <p> 910 * For a double value <code>x</code>, this method returns 911 * <code>+1.0</code> if <code>x > 0</code>, <code>0.0</code> if 912 * <code>x = 0.0</code>, and <code>-1.0</code> if <code>x < 0</code>. 913 * Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>.</p> 914 * 915 * @param x the value, a double 916 * @return +1.0, 0.0, or -1.0, depending on the sign of x 917 */ 918 public static double sign(final double x) { 919 if (Double.isNaN(x)) { 920 return Double.NaN; 921 } 922 return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; 923 } 924 925 /** 926 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 927 * for float value <code>x</code>. 928 * <p> 929 * For a float value x, this method returns +1.0F if x > 0, 0.0F if x = 930 * 0.0F, and -1.0F if x < 0. Returns <code>NaN</code> if <code>x</code> 931 * is <code>NaN</code>.</p> 932 * 933 * @param x the value, a float 934 * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x 935 */ 936 public static float sign(final float x) { 937 if (Float.isNaN(x)) { 938 return Float.NaN; 939 } 940 return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; 941 } 942 943 /** 944 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 945 * for int value <code>x</code>. 946 * <p> 947 * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1 948 * if x < 0.</p> 949 * 950 * @param x the value, an int 951 * @return +1, 0, or -1, depending on the sign of x 952 */ 953 public static int sign(final int x) { 954 return (x == 0) ? 0 : (x > 0) ? 1 : -1; 955 } 956 957 /** 958 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 959 * for long value <code>x</code>. 960 * <p> 961 * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and 962 * -1L if x < 0.</p> 963 * 964 * @param x the value, a long 965 * @return +1L, 0L, or -1L, depending on the sign of x 966 */ 967 public static long sign(final long x) { 968 return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; 969 } 970 971 /** 972 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 973 * for short value <code>x</code>. 974 * <p> 975 * For a short value x, this method returns (short)(+1) if x > 0, (short)(0) 976 * if x = 0, and (short)(-1) if x < 0.</p> 977 * 978 * @param x the value, a short 979 * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of 980 * x 981 */ 982 public static short sign(final short x) { 983 return (x == ZS) ? ZS : (x > ZS) ? PS : NS; 984 } 985 986 /** 987 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html"> 988 * hyperbolic sine</a> of x. 989 * 990 * @param x double value for which to find the hyperbolic sine 991 * @return hyperbolic sine of x 992 */ 993 public static double sinh(double x) { 994 return (Math.exp(x) - Math.exp(-x)) / 2.0; 995 } 996 997 /** 998 * Subtract two integers, checking for overflow. 999 * 1000 * @param x the minuend 1001 * @param y the subtrahend 1002 * @return the difference <code>x-y</code> 1003 * @throws ArithmeticException if the result can not be represented as an 1004 * int 1005 * @since 1.1 1006 */ 1007 public static int subAndCheck(int x, int y) { 1008 long s = (long)x - (long)y; 1009 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { 1010 throw new ArithmeticException("overflow: subtract"); 1011 } 1012 return (int)s; 1013 } 1014 1015 /** 1016 * Subtract two long integers, checking for overflow. 1017 * 1018 * @param a first value 1019 * @param b second value 1020 * @return the difference <code>a-b</code> 1021 * @throws ArithmeticException if the result can not be represented as an 1022 * long 1023 * @since 1.2 1024 */ 1025 public static long subAndCheck(long a, long b) { 1026 long ret; 1027 String msg = "overflow: subtract"; 1028 if (b == Long.MIN_VALUE) { 1029 if (a < 0) { 1030 ret = a - b; 1031 } else { 1032 throw new ArithmeticException(msg); 1033 } 1034 } else { 1035 // use additive inverse 1036 ret = addAndCheck(a, -b, msg); 1037 } 1038 return ret; 1039 } 1040 1041 }