1 /* 2 * Copyright 2003-2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.commons.math.util; 18 19 import java.math.BigDecimal; 20 21 /** 22 * Some useful additions to the built-in functions in {@link Math}. 23 * @version $Revision: 321510 $ $Date: 2005-10-15 15:33:14 -0700 (Sat, 15 Oct 2005) $ 24 */ 25 public final class MathUtils { 26 27 /** -1.0 cast as a byte. */ 28 private static final byte NB = (byte)-1; 29 30 /** -1.0 cast as a short. */ 31 private static final short NS = (short)-1; 32 33 /** 1.0 cast as a byte. */ 34 private static final byte PB = (byte)1; 35 36 /** 1.0 cast as a short. */ 37 private static final short PS = (short)1; 38 39 /** 0.0 cast as a byte. */ 40 private static final byte ZB = (byte)0; 41 42 /** 0.0 cast as a short. */ 43 private static final short ZS = (short)0; 44 45 /** 46 * Private Constructor 47 */ 48 private MathUtils() { 49 super(); 50 } 51 52 /** 53 * Add two integers, checking for overflow. 54 * 55 * @param x an addend 56 * @param y an addend 57 * @return the sum <code>x+y</code> 58 * @throws ArithmeticException if the result can not be represented as an 59 * int 60 * @since 1.1 61 */ 62 public static int addAndCheck(int x, int y) { 63 long s = (long)x + (long)y; 64 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { 65 throw new ArithmeticException("overflow: add"); 66 } 67 return (int)s; 68 } 69 70 /** 71 * Returns an exact representation of the <a 72 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 73 * Coefficient</a>, "<code>n choose k</code>", the number of 74 * <code>k</code>-element subsets that can be selected from an 75 * <code>n</code>-element set. 76 * <p> 77 * <Strong>Preconditions</strong>: 78 * <ul> 79 * <li> <code>0 <= k <= n </code> (otherwise 80 * <code>IllegalArgumentException</code> is thrown)</li> 81 * <li> The result is small enough to fit into a <code>long</code>. The 82 * largest value of <code>n</code> for which all coefficients are 83 * <code> < Long.MAX_VALUE</code> is 66. If the computed value exceeds 84 * <code>Long.MAX_VALUE</code> an <code>ArithMeticException 85 * </code> is 86 * thrown.</li> 87 * </ul> 88 * 89 * @param n the size of the set 90 * @param k the size of the subsets to be counted 91 * @return <code>n choose k</code> 92 * @throws IllegalArgumentException if preconditions are not met. 93 * @throws ArithmeticException if the result is too large to be represented 94 * by a long integer. 95 */ 96 public static long binomialCoefficient(final int n, final int k) { 97 if (n < k) { 98 throw new IllegalArgumentException( 99 "must have n >= k for binomial coefficient (n,k)"); 100 } 101 if (n < 0) { 102 throw new IllegalArgumentException( 103 "must have n >= 0 for binomial coefficient (n,k)"); 104 } 105 if ((n == k) || (k == 0)) { 106 return 1; 107 } 108 if ((k == 1) || (k == n - 1)) { 109 return n; 110 } 111 112 long result = Math.round(binomialCoefficientDouble(n, k)); 113 if (result == Long.MAX_VALUE) { 114 throw new ArithmeticException( 115 "result too large to represent in a long integer"); 116 } 117 return result; 118 } 119 120 /** 121 * Returns a <code>double</code> representation of the <a 122 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 123 * Coefficient</a>, "<code>n choose k</code>", the number of 124 * <code>k</code>-element subsets that can be selected from an 125 * <code>n</code>-element set. 126 * <p> 127 * <Strong>Preconditions</strong>: 128 * <ul> 129 * <li> <code>0 <= k <= n </code> (otherwise 130 * <code>IllegalArgumentException</code> is thrown)</li> 131 * <li> The result is small enough to fit into a <code>double</code>. The 132 * largest value of <code>n</code> for which all coefficients are < 133 * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE, 134 * Double.POSITIVE_INFINITY is returned</li> 135 * </ul> 136 * 137 * @param n the size of the set 138 * @param k the size of the subsets to be counted 139 * @return <code>n choose k</code> 140 * @throws IllegalArgumentException if preconditions are not met. 141 */ 142 public static double binomialCoefficientDouble(final int n, final int k) { 143 return Math.floor(Math.exp(binomialCoefficientLog(n, k)) + 0.5); 144 } 145 146 /** 147 * Returns the natural <code>log</code> of the <a 148 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial 149 * Coefficient</a>, "<code>n choose k</code>", the number of 150 * <code>k</code>-element subsets that can be selected from an 151 * <code>n</code>-element set. 152 * <p> 153 * <Strong>Preconditions</strong>: 154 * <ul> 155 * <li> <code>0 <= k <= n </code> (otherwise 156 * <code>IllegalArgumentException</code> is thrown)</li> 157 * </ul> 158 * 159 * @param n the size of the set 160 * @param k the size of the subsets to be counted 161 * @return <code>n choose k</code> 162 * @throws IllegalArgumentException if preconditions are not met. 163 */ 164 public static double binomialCoefficientLog(final int n, final int k) { 165 if (n < k) { 166 throw new IllegalArgumentException( 167 "must have n >= k for binomial coefficient (n,k)"); 168 } 169 if (n < 0) { 170 throw new IllegalArgumentException( 171 "must have n >= 0 for binomial coefficient (n,k)"); 172 } 173 if ((n == k) || (k == 0)) { 174 return 0; 175 } 176 if ((k == 1) || (k == n - 1)) { 177 return Math.log((double)n); 178 } 179 double logSum = 0; 180 181 // n!/k! 182 for (int i = k + 1; i <= n; i++) { 183 logSum += Math.log((double)i); 184 } 185 186 // divide by (n-k)! 187 for (int i = 2; i <= n - k; i++) { 188 logSum -= Math.log((double)i); 189 } 190 191 return logSum; 192 } 193 194 /** 195 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html"> 196 * hyperbolic cosine</a> of x. 197 * 198 * @param x double value for which to find the hyperbolic cosine 199 * @return hyperbolic cosine of x 200 */ 201 public static double cosh(double x) { 202 return (Math.exp(x) + Math.exp(-x)) / 2.0; 203 } 204 205 /** 206 * Returns true iff both arguments are NaN or neither is NaN and they are 207 * equal 208 * 209 * @param x first value 210 * @param y second value 211 * @return true if the values are equal or both are NaN 212 */ 213 public static boolean equals(double x, double y) { 214 return ((Double.isNaN(x) && Double.isNaN(y)) || x == y); 215 } 216 217 /** 218 * Returns n!. Shorthand for <code>n</code> <a 219 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the 220 * product of the numbers <code>1,...,n</code>. 221 * <p> 222 * <Strong>Preconditions</strong>: 223 * <ul> 224 * <li> <code>n >= 0</code> (otherwise 225 * <code>IllegalArgumentException</code> is thrown)</li> 226 * <li> The result is small enough to fit into a <code>long</code>. The 227 * largest value of <code>n</code> for which <code>n!</code> < 228 * Long.MAX_VALUE</code> is 20. If the computed value exceeds <code>Long.MAX_VALUE</code> 229 * an <code>ArithMeticException </code> is thrown.</li> 230 * </ul> 231 * </p> 232 * 233 * @param n argument 234 * @return <code>n!</code> 235 * @throws ArithmeticException if the result is too large to be represented 236 * by a long integer. 237 * @throws IllegalArgumentException if n < 0 238 */ 239 public static long factorial(final int n) { 240 long result = Math.round(factorialDouble(n)); 241 if (result == Long.MAX_VALUE) { 242 throw new ArithmeticException( 243 "result too large to represent in a long integer"); 244 } 245 return result; 246 } 247 248 /** 249 * Returns n!. Shorthand for <code>n</code> <a 250 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the 251 * product of the numbers <code>1,...,n</code> as a <code>double</code>. 252 * <p> 253 * <Strong>Preconditions</strong>: 254 * <ul> 255 * <li> <code>n >= 0</code> (otherwise 256 * <code>IllegalArgumentException</code> is thrown)</li> 257 * <li> The result is small enough to fit into a <code>double</code>. The 258 * largest value of <code>n</code> for which <code>n!</code> < 259 * Double.MAX_VALUE</code> is 170. If the computed value exceeds 260 * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li> 261 * </ul> 262 * </p> 263 * 264 * @param n argument 265 * @return <code>n!</code> 266 * @throws IllegalArgumentException if n < 0 267 */ 268 public static double factorialDouble(final int n) { 269 if (n < 0) { 270 throw new IllegalArgumentException("must have n >= 0 for n!"); 271 } 272 return Math.floor(Math.exp(factorialLog(n)) + 0.5); 273 } 274 275 /** 276 * Returns the natural logarithm of n!. 277 * <p> 278 * <Strong>Preconditions</strong>: 279 * <ul> 280 * <li> <code>n >= 0</code> (otherwise 281 * <code>IllegalArgumentException</code> is thrown)</li> 282 * </ul> 283 * 284 * @param n argument 285 * @return <code>n!</code> 286 * @throws IllegalArgumentException if preconditions are not met. 287 */ 288 public static double factorialLog(final int n) { 289 if (n < 0) { 290 throw new IllegalArgumentException("must have n > 0 for n!"); 291 } 292 double logSum = 0; 293 for (int i = 2; i <= n; i++) { 294 logSum += Math.log((double)i); 295 } 296 return logSum; 297 } 298 299 /** 300 * <p> 301 * Gets the greatest common divisor of the absolute value of two numbers, 302 * using the "binary gcd" method which avoids division and modulo 303 * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef 304 * Stein (1961). 305 * </p> 306 * 307 * @param u a non-zero number 308 * @param v a non-zero number 309 * @return the greatest common divisor, never zero 310 * @since 1.1 311 */ 312 public static int gcd(int u, int v) { 313 if (u * v == 0) { 314 return (Math.abs(u) + Math.abs(v)); 315 } 316 // keep u and v negative, as negative integers range down to 317 // -2^31, while positive numbers can only be as large as 2^31-1 318 // (i.e. we can't necessarily negate a negative number without 319 // overflow) 320 /* assert u!=0 && v!=0; */ 321 if (u > 0) { 322 u = -u; 323 } // make u negative 324 if (v > 0) { 325 v = -v; 326 } // make v negative 327 // B1. [Find power of 2] 328 int k = 0; 329 while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are 330 // both even... 331 u /= 2; 332 v /= 2; 333 k++; // cast out twos. 334 } 335 if (k == 31) { 336 throw new ArithmeticException("overflow: gcd is 2^31"); 337 } 338 // B2. Initialize: u and v have been divided by 2^k and at least 339 // one is odd. 340 int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; 341 // t negative: u was odd, v may be even (t replaces v) 342 // t positive: u was even, v is odd (t replaces u) 343 do { 344 /* assert u<0 && v<0; */ 345 // B4/B3: cast out twos from t. 346 while ((t & 1) == 0) { // while t is even.. 347 t /= 2; // cast out twos 348 } 349 // B5 [reset max(u,v)] 350 if (t > 0) { 351 u = -t; 352 } else { 353 v = t; 354 } 355 // B6/B3. at this point both u and v should be odd. 356 t = (v - u) / 2; 357 // |u| larger: t positive (replace u) 358 // |v| larger: t negative (replace v) 359 } while (t != 0); 360 return -u * (1 << k); // gcd is u*2^k 361 } 362 363 /** 364 * Returns an integer hash code representing the given double value. 365 * 366 * @param value the value to be hashed 367 * @return the hash code 368 */ 369 public static int hash(double value) { 370 long bits = Double.doubleToLongBits(value); 371 return (int)(bits ^ (bits >>> 32)); 372 } 373 374 /** 375 * For a byte value x, this method returns (byte)(+1) if x >= 0 and 376 * (byte)(-1) if x < 0. 377 * 378 * @param x the value, a byte 379 * @return (byte)(+1) or (byte)(-1), depending on the sign of x 380 */ 381 public static byte indicator(final byte x) { 382 return (x >= ZB) ? PB : NB; 383 } 384 385 /** 386 * For a double precision value x, this method returns +1.0 if x >= 0 and 387 * -1.0 if x < 0. Returns <code>NaN</code> if <code>x</code> is 388 * <code>NaN</code>. 389 * 390 * @param x the value, a double 391 * @return +1.0 or -1.0, depending on the sign of x 392 */ 393 public static double indicator(final double x) { 394 if (Double.isNaN(x)) { 395 return Double.NaN; 396 } 397 return (x >= 0.0) ? 1.0 : -1.0; 398 } 399 400 /** 401 * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x < 402 * 0. Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>. 403 * 404 * @param x the value, a float 405 * @return +1.0F or -1.0F, depending on the sign of x 406 */ 407 public static float indicator(final float x) { 408 if (Float.isNaN(x)) { 409 return Float.NaN; 410 } 411 return (x >= 0.0F) ? 1.0F : -1.0F; 412 } 413 414 /** 415 * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0. 416 * 417 * @param x the value, an int 418 * @return +1 or -1, depending on the sign of x 419 */ 420 public static int indicator(final int x) { 421 return (x >= 0) ? 1 : -1; 422 } 423 424 /** 425 * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0. 426 * 427 * @param x the value, a long 428 * @return +1L or -1L, depending on the sign of x 429 */ 430 public static long indicator(final long x) { 431 return (x >= 0L) ? 1L : -1L; 432 } 433 434 /** 435 * For a short value x, this method returns (short)(+1) if x >= 0 and 436 * (short)(-1) if x < 0. 437 * 438 * @param x the value, a short 439 * @return (short)(+1) or (short)(-1), depending on the sign of x 440 */ 441 public static short indicator(final short x) { 442 return (x >= ZS) ? PS : NS; 443 } 444 445 /** 446 * Returns the least common multiple between two integer values. 447 * 448 * @param a the first integer value. 449 * @param b the second integer value. 450 * @return the least common multiple between a and b. 451 * @throws ArithmeticException if the lcm is too large to store as an int 452 * @since 1.1 453 */ 454 public static int lcm(int a, int b) { 455 return Math.abs(mulAndCheck(a / gcd(a, b), b)); 456 } 457 458 /** 459 * Multiply two integers, checking for overflow. 460 * 461 * @param x a factor 462 * @param y a factor 463 * @return the product <code>x*y</code> 464 * @throws ArithmeticException if the result can not be represented as an 465 * int 466 * @since 1.1 467 */ 468 public static int mulAndCheck(int x, int y) { 469 long m = ((long)x) * ((long)y); 470 if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) { 471 throw new ArithmeticException("overflow: mul"); 472 } 473 return (int)m; 474 } 475 476 /** 477 * Round the given value to the specified number of decimal places. The 478 * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. 479 * 480 * @param x the value to round. 481 * @param scale the number of digits to the right of the decimal point. 482 * @return the rounded value. 483 * @since 1.1 484 */ 485 public static double round(double x, int scale) { 486 return round(x, scale, BigDecimal.ROUND_HALF_UP); 487 } 488 489 /** 490 * Round the given value to the specified number of decimal places. The 491 * value is rounded using the given method which is any method defined in 492 * {@link BigDecimal}. 493 * 494 * @param x the value to round. 495 * @param scale the number of digits to the right of the decimal point. 496 * @param roundingMethod the rounding method as defined in 497 * {@link BigDecimal}. 498 * @return the rounded value. 499 * @since 1.1 500 */ 501 public static double round(double x, int scale, int roundingMethod) { 502 double sign = indicator(x); 503 double factor = Math.pow(10.0, scale) * sign; 504 return roundUnscaled(x * factor, sign, roundingMethod) / factor; 505 } 506 507 /** 508 * Round the given value to the specified number of decimal places. The 509 * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method. 510 * 511 * @param x the value to round. 512 * @param scale the number of digits to the right of the decimal point. 513 * @return the rounded value. 514 * @since 1.1 515 */ 516 public static float round(float x, int scale) { 517 return round(x, scale, BigDecimal.ROUND_HALF_UP); 518 } 519 520 /** 521 * Round the given value to the specified number of decimal places. The 522 * value is rounded using the given method which is any method defined in 523 * {@link BigDecimal}. 524 * 525 * @param x the value to round. 526 * @param scale the number of digits to the right of the decimal point. 527 * @param roundingMethod the rounding method as defined in 528 * {@link BigDecimal}. 529 * @return the rounded value. 530 * @since 1.1 531 */ 532 public static float round(float x, int scale, int roundingMethod) { 533 float sign = indicator(x); 534 float factor = (float)Math.pow(10.0f, scale) * sign; 535 return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor; 536 } 537 538 /** 539 * Round the given non-negative, value to the "nearest" integer. Nearest is 540 * determined by the rounding method specified. Rounding methods are defined 541 * in {@link BigDecimal}. 542 * 543 * @param unscaled the value to round. 544 * @param sign the sign of the original, scaled value. 545 * @param roundingMethod the rounding method as defined in 546 * {@link BigDecimal}. 547 * @return the rounded value. 548 * @since 1.1 549 */ 550 private static double roundUnscaled(double unscaled, double sign, 551 int roundingMethod) { 552 switch (roundingMethod) { 553 case BigDecimal.ROUND_CEILING : 554 if (sign == -1) { 555 unscaled = Math.floor(unscaled); 556 } else { 557 unscaled = Math.ceil(unscaled); 558 } 559 break; 560 case BigDecimal.ROUND_DOWN : 561 unscaled = Math.floor(unscaled); 562 break; 563 case BigDecimal.ROUND_FLOOR : 564 if (sign == -1) { 565 unscaled = Math.ceil(unscaled); 566 } else { 567 unscaled = Math.floor(unscaled); 568 } 569 break; 570 case BigDecimal.ROUND_HALF_DOWN : { 571 double fraction = Math.abs(unscaled - Math.floor(unscaled)); 572 if (fraction > 0.5) { 573 unscaled = Math.ceil(unscaled); 574 } else { 575 unscaled = Math.floor(unscaled); 576 } 577 break; 578 } 579 case BigDecimal.ROUND_HALF_EVEN : { 580 double fraction = Math.abs(unscaled - Math.floor(unscaled)); 581 if (fraction > 0.5) { 582 unscaled = Math.ceil(unscaled); 583 } else if (fraction < 0.5) { 584 unscaled = Math.floor(unscaled); 585 } else { 586 if (Math.floor(unscaled) / 2.0 == Math.floor(Math 587 .floor(unscaled) / 2.0)) { // even 588 unscaled = Math.floor(unscaled); 589 } else { // odd 590 unscaled = Math.ceil(unscaled); 591 } 592 } 593 break; 594 } 595 case BigDecimal.ROUND_HALF_UP : { 596 double fraction = Math.abs(unscaled - Math.floor(unscaled)); 597 if (fraction >= 0.5) { 598 unscaled = Math.ceil(unscaled); 599 } else { 600 unscaled = Math.floor(unscaled); 601 } 602 break; 603 } 604 case BigDecimal.ROUND_UNNECESSARY : 605 if (unscaled != Math.floor(unscaled)) { 606 throw new ArithmeticException("Inexact result from rounding"); 607 } 608 break; 609 case BigDecimal.ROUND_UP : 610 unscaled = Math.ceil(unscaled); 611 break; 612 default : 613 throw new IllegalArgumentException("Invalid rounding method."); 614 } 615 return unscaled; 616 } 617 618 /** 619 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 620 * for byte value <code>x</code>. 621 * <p> 622 * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if 623 * x = 0, and (byte)(-1) if x < 0. 624 * 625 * @param x the value, a byte 626 * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x 627 */ 628 public static byte sign(final byte x) { 629 return (x == ZB) ? ZB : (x > ZB) ? PB : NB; 630 } 631 632 /** 633 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 634 * for double precision <code>x</code>. 635 * <p> 636 * For a double value <code>x</code>, this method returns 637 * <code>+1.0</code> if <code>x > 0</code>, <code>0.0</code> if 638 * <code>x = 0.0</code>, and <code>-1.0</code> if <code>x < 0</code>. 639 * Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>. 640 * 641 * @param x the value, a double 642 * @return +1.0, 0.0, or -1.0, depending on the sign of x 643 */ 644 public static double sign(final double x) { 645 if (Double.isNaN(x)) { 646 return Double.NaN; 647 } 648 return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; 649 } 650 651 /** 652 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 653 * for float value <code>x</code>. 654 * <p> 655 * For a float value x, this method returns +1.0F if x > 0, 0.0F if x = 656 * 0.0F, and -1.0F if x < 0. Returns <code>NaN</code> if <code>x</code> 657 * is <code>NaN</code>. 658 * 659 * @param x the value, a float 660 * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x 661 */ 662 public static float sign(final float x) { 663 if (Float.isNaN(x)) { 664 return Float.NaN; 665 } 666 return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; 667 } 668 669 /** 670 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 671 * for int value <code>x</code>. 672 * <p> 673 * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1 674 * if x < 0. 675 * 676 * @param x the value, an int 677 * @return +1, 0, or -1, depending on the sign of x 678 */ 679 public static int sign(final int x) { 680 return (x == 0) ? 0 : (x > 0) ? 1 : -1; 681 } 682 683 /** 684 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 685 * for long value <code>x</code>. 686 * <p> 687 * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and 688 * -1L if x < 0. 689 * 690 * @param x the value, a long 691 * @return +1L, 0L, or -1L, depending on the sign of x 692 */ 693 public static long sign(final long x) { 694 return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; 695 } 696 697 /** 698 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> 699 * for short value <code>x</code>. 700 * <p> 701 * For a short value x, this method returns (short)(+1) if x > 0, (short)(0) 702 * if x = 0, and (short)(-1) if x < 0. 703 * 704 * @param x the value, a short 705 * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of 706 * x 707 */ 708 public static short sign(final short x) { 709 return (x == ZS) ? ZS : (x > ZS) ? PS : NS; 710 } 711 712 /** 713 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html"> 714 * hyperbolic sine</a> of x. 715 * 716 * @param x double value for which to find the hyperbolic sine 717 * @return hyperbolic sine of x 718 */ 719 public static double sinh(double x) { 720 return (Math.exp(x) - Math.exp(-x)) / 2.0; 721 } 722 723 /** 724 * Subtract two integers, checking for overflow. 725 * 726 * @param x the minuend 727 * @param y the subtrahend 728 * @return the difference <code>x-y</code> 729 * @throws ArithmeticException if the result can not be represented as an 730 * int 731 * @since 1.1 732 */ 733 public static int subAndCheck(int x, int y) { 734 long s = (long)x - (long)y; 735 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { 736 throw new ArithmeticException("overflow: subtract"); 737 } 738 return (int)s; 739 } 740 }