View Javadoc

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 }