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 }