libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / java / math / BigDecimal.java
blobeceaf8cddc24bb4a44c96bc43a0863984a940772
1 /* java.math.BigDecimal -- Arbitrary precision decimals.
2 Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.math;
40 import gnu.java.lang.CPStringBuilder;
42 public class BigDecimal extends Number implements Comparable<BigDecimal>
44 private BigInteger intVal;
45 private int scale;
46 private int precision = 0;
47 private static final long serialVersionUID = 6108874887143696463L;
49 /**
50 * The constant zero as a BigDecimal with scale zero.
51 * @since 1.5
53 public static final BigDecimal ZERO =
54 new BigDecimal (BigInteger.ZERO, 0);
56 /**
57 * The constant one as a BigDecimal with scale zero.
58 * @since 1.5
60 public static final BigDecimal ONE =
61 new BigDecimal (BigInteger.ONE, 0);
63 /**
64 * The constant ten as a BigDecimal with scale zero.
65 * @since 1.5
67 public static final BigDecimal TEN =
68 new BigDecimal (BigInteger.TEN, 0);
70 public static final int ROUND_UP = 0;
71 public static final int ROUND_DOWN = 1;
72 public static final int ROUND_CEILING = 2;
73 public static final int ROUND_FLOOR = 3;
74 public static final int ROUND_HALF_UP = 4;
75 public static final int ROUND_HALF_DOWN = 5;
76 public static final int ROUND_HALF_EVEN = 6;
77 public static final int ROUND_UNNECESSARY = 7;
79 /**
80 * Constructs a new BigDecimal whose unscaled value is val and whose
81 * scale is zero.
82 * @param val the value of the new BigDecimal
83 * @since 1.5
85 public BigDecimal (int val)
87 this.intVal = BigInteger.valueOf(val);
88 this.scale = 0;
91 /**
92 * Constructs a BigDecimal using the BigDecimal(int) constructor and then
93 * rounds according to the MathContext.
94 * @param val the value for the initial (unrounded) BigDecimal
95 * @param mc the MathContext specifying the rounding
96 * @throws ArithmeticException if the result is inexact but the rounding type
97 * is RoundingMode.UNNECESSARY
98 * @since 1.5
100 public BigDecimal (int val, MathContext mc)
102 this (val);
103 if (mc.getPrecision() != 0)
105 BigDecimal result = this.round(mc);
106 this.intVal = result.intVal;
107 this.scale = result.scale;
108 this.precision = result.precision;
113 * Constructs a new BigDecimal whose unscaled value is val and whose
114 * scale is zero.
115 * @param val the value of the new BigDecimal
117 public BigDecimal (long val)
119 this.intVal = BigInteger.valueOf(val);
120 this.scale = 0;
124 * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
125 * and then rounds according to the MathContext.
126 * @param val the long from which we create the initial BigDecimal
127 * @param mc the MathContext that specifies the rounding behaviour
128 * @throws ArithmeticException if the result is inexact but the rounding type
129 * is RoundingMode.UNNECESSARY
130 * @since 1.5
132 public BigDecimal (long val, MathContext mc)
134 this(val);
135 if (mc.getPrecision() != 0)
137 BigDecimal result = this.round(mc);
138 this.intVal = result.intVal;
139 this.scale = result.scale;
140 this.precision = result.precision;
145 * Constructs a BigDecimal whose value is given by num rounded according to
146 * mc. Since num is already a BigInteger, the rounding refers only to the
147 * precision setting in mc, if mc.getPrecision() returns an int lower than
148 * the number of digits in num, then rounding is necessary.
149 * @param num the unscaledValue, before rounding
150 * @param mc the MathContext that specifies the precision
151 * @throws ArithmeticException if the result is inexact but the rounding type
152 * is RoundingMode.UNNECESSARY
153 * * @since 1.5
155 public BigDecimal (BigInteger num, MathContext mc)
157 this (num, 0);
158 if (mc.getPrecision() != 0)
160 BigDecimal result = this.round(mc);
161 this.intVal = result.intVal;
162 this.scale = result.scale;
163 this.precision = result.precision;
168 * Constructs a BigDecimal from the String val according to the same
169 * rules as the BigDecimal(String) constructor and then rounds
170 * according to the MathContext mc.
171 * @param val the String from which we construct the initial BigDecimal
172 * @param mc the MathContext that specifies the rounding
173 * @throws ArithmeticException if the result is inexact but the rounding type
174 * is RoundingMode.UNNECESSARY
175 * @since 1.5
177 public BigDecimal (String val, MathContext mc)
179 this (val);
180 if (mc.getPrecision() != 0)
182 BigDecimal result = this.round(mc);
183 this.intVal = result.intVal;
184 this.scale = result.scale;
185 this.precision = result.precision;
190 * Constructs a BigDecimal whose unscaled value is num and whose
191 * scale is zero.
192 * @param num the value of the new BigDecimal
194 public BigDecimal (BigInteger num)
196 this (num, 0);
200 * Constructs a BigDecimal whose unscaled value is num and whose
201 * scale is scale.
202 * @param num
203 * @param scale
205 public BigDecimal (BigInteger num, int scale)
207 this.intVal = num;
208 this.scale = scale;
212 * Constructs a BigDecimal using the BigDecimal(BigInteger, int)
213 * constructor and then rounds according to the MathContext.
214 * @param num the unscaled value of the unrounded BigDecimal
215 * @param scale the scale of the unrounded BigDecimal
216 * @param mc the MathContext specifying the rounding
217 * @throws ArithmeticException if the result is inexact but the rounding type
218 * is RoundingMode.UNNECESSARY
219 * @since 1.5
221 public BigDecimal (BigInteger num, int scale, MathContext mc)
223 this (num, scale);
224 if (mc.getPrecision() != 0)
226 BigDecimal result = this.round(mc);
227 this.intVal = result.intVal;
228 this.scale = result.scale;
229 this.precision = result.precision;
234 * Constructs a BigDecimal in the same way as BigDecimal(double) and then
235 * rounds according to the MathContext.
236 * @param num the double from which the initial BigDecimal is created
237 * @param mc the MathContext that specifies the rounding behaviour
238 * @throws ArithmeticException if the result is inexact but the rounding type
239 * is RoundingMode.UNNECESSARY
240 * @since 1.5
242 public BigDecimal (double num, MathContext mc)
244 this (num);
245 if (mc.getPrecision() != 0)
247 BigDecimal result = this.round(mc);
248 this.intVal = result.intVal;
249 this.scale = result.scale;
250 this.precision = result.precision;
254 public BigDecimal (double num) throws NumberFormatException
256 if (Double.isInfinite (num) || Double.isNaN (num))
257 throw new NumberFormatException ("invalid argument: " + num);
258 // Note we can't convert NUM to a String and then use the
259 // String-based constructor. The BigDecimal documentation makes
260 // it clear that the two constructors work differently.
262 final int mantissaBits = 52;
263 final int exponentBits = 11;
264 final long mantMask = (1L << mantissaBits) - 1;
265 final long expMask = (1L << exponentBits) - 1;
267 long bits = Double.doubleToLongBits (num);
268 long mantissa = bits & mantMask;
269 long exponent = (bits >>> mantissaBits) & expMask;
270 boolean denormal = exponent == 0;
272 // Correct the exponent for the bias.
273 exponent -= denormal ? 1022 : 1023;
275 // Now correct the exponent to account for the bits to the right
276 // of the decimal.
277 exponent -= mantissaBits;
278 // Ordinary numbers have an implied leading `1' bit.
279 if (! denormal)
280 mantissa |= (1L << mantissaBits);
282 // Shave off factors of 10.
283 while (exponent < 0 && (mantissa & 1) == 0)
285 ++exponent;
286 mantissa >>= 1;
289 intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
290 if (exponent < 0)
292 // We have MANTISSA * 2 ^ (EXPONENT).
293 // Since (1/2)^N == 5^N * 10^-N we can easily convert this
294 // into a power of 10.
295 scale = (int) (- exponent);
296 BigInteger mult = BigInteger.valueOf (5).pow (scale);
297 intVal = intVal.multiply (mult);
299 else
301 intVal = intVal.shiftLeft ((int) exponent);
302 scale = 0;
307 * Constructs a BigDecimal from the char subarray and rounding
308 * according to the MathContext.
309 * @param in the char array
310 * @param offset the start of the subarray
311 * @param len the length of the subarray
312 * @param mc the MathContext for rounding
313 * @throws NumberFormatException if the char subarray is not a valid
314 * BigDecimal representation
315 * @throws ArithmeticException if the result is inexact but the rounding
316 * mode is RoundingMode.UNNECESSARY
317 * @since 1.5
319 public BigDecimal(char[] in, int offset, int len, MathContext mc)
321 this(in, offset, len);
322 // If mc has precision other than zero then we must round.
323 if (mc.getPrecision() != 0)
325 BigDecimal temp = this.round(mc);
326 this.intVal = temp.intVal;
327 this.scale = temp.scale;
328 this.precision = temp.precision;
333 * Constructs a BigDecimal from the char array and rounding according
334 * to the MathContext.
335 * @param in the char array
336 * @param mc the MathContext
337 * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
338 * representation
339 * @throws ArithmeticException if the result is inexact but the rounding mode
340 * is RoundingMode.UNNECESSARY
341 * @since 1.5
343 public BigDecimal(char[] in, MathContext mc)
345 this(in, 0, in.length);
346 // If mc has precision other than zero then we must round.
347 if (mc.getPrecision() != 0)
349 BigDecimal temp = this.round(mc);
350 this.intVal = temp.intVal;
351 this.scale = temp.scale;
352 this.precision = temp.precision;
357 * Constructs a BigDecimal from the given char array, accepting the same
358 * sequence of characters as the BigDecimal(String) constructor.
359 * @param in the char array
360 * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
361 * representation
362 * @since 1.5
364 public BigDecimal(char[] in)
366 this(in, 0, in.length);
370 * Constructs a BigDecimal from a char subarray, accepting the same sequence
371 * of characters as the BigDecimal(String) constructor.
372 * @param in the char array
373 * @param offset the start of the subarray
374 * @param len the length of the subarray
375 * @throws NumberFormatException if <code>in</code> is not a valid
376 * BigDecimal representation.
377 * @since 1.5
379 public BigDecimal(char[] in, int offset, int len)
381 // start is the index into the char array where the significand starts
382 int start = offset;
383 // end is one greater than the index of the last character used
384 int end = offset + len;
385 // point is the index into the char array where the exponent starts
386 // (or, if there is no exponent, this is equal to end)
387 int point = offset;
388 // dot is the index into the char array where the decimal point is
389 // found, or -1 if there is no decimal point
390 int dot = -1;
392 // The following examples show what these variables mean. Note that
393 // point and dot don't yet have the correct values, they will be
394 // properly assigned in a loop later on in this method.
396 // Example 1
398 // + 1 0 2 . 4 6 9
399 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
401 // offset = 2, len = 8, start = 3, dot = 6, point = end = 10
403 // Example 2
405 // + 2 3 4 . 6 1 3 E - 1
406 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
408 // offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
410 // Example 3
412 // - 1 2 3 4 5 e 7
413 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
415 // offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
417 // Determine the sign of the number.
418 boolean negative = false;
419 if (in[offset] == '+')
421 ++start;
422 ++point;
424 else if (in[offset] == '-')
426 ++start;
427 ++point;
428 negative = true;
431 // Check each character looking for the decimal point and the
432 // start of the exponent.
433 while (point < end)
435 char c = in[point];
436 if (c == '.')
438 // If dot != -1 then we've seen more than one decimal point.
439 if (dot != -1)
440 throw new NumberFormatException("multiple `.'s in number");
441 dot = point;
443 // Break when we reach the start of the exponent.
444 else if (c == 'e' || c == 'E')
445 break;
446 // Throw an exception if the character was not a decimal or an
447 // exponent and is not a digit.
448 else if (!Character.isDigit(c))
449 throw new NumberFormatException("unrecognized character at " + point
450 + ": " + c);
451 ++point;
454 // val is a StringBuilder from which we'll create a BigInteger
455 // which will be the unscaled value for this BigDecimal
456 CPStringBuilder val = new CPStringBuilder(point - start - 1);
457 if (dot != -1)
459 // If there was a decimal we must combine the two parts that
460 // contain only digits and we must set the scale properly.
461 val.append(in, start, dot - start);
462 val.append(in, dot + 1, point - dot - 1);
463 scale = point - 1 - dot;
465 else
467 // If there was no decimal then the unscaled value is just the number
468 // formed from all the digits and the scale is zero.
469 val.append(in, start, point - start);
470 scale = 0;
472 if (val.length() == 0)
473 throw new NumberFormatException("no digits seen");
475 // Prepend a negative sign if necessary.
476 if (negative)
477 val.insert(0, '-');
478 intVal = new BigInteger(val.toString());
480 // Now parse exponent.
481 // If point < end that means we broke out of the previous loop when we
482 // saw an 'e' or an 'E'.
483 if (point < end)
485 point++;
486 // Ignore a '+' sign.
487 if (in[point] == '+')
488 point++;
490 // Throw an exception if there were no digits found after the 'e'
491 // or 'E'.
492 if (point >= end)
493 throw new NumberFormatException("no exponent following e or E");
497 // Adjust the scale according to the exponent.
498 // Remember that the value of a BigDecimal is
499 // unscaledValue x Math.pow(10, -scale)
500 scale -= Integer.parseInt(new String(in, point, end - point));
502 catch (NumberFormatException ex)
504 throw new NumberFormatException("malformed exponent");
509 public BigDecimal (String num) throws NumberFormatException
511 int len = num.length();
512 int start = 0, point = 0;
513 int dot = -1;
514 boolean negative = false;
515 if (num.charAt(0) == '+')
517 ++start;
518 ++point;
520 else if (num.charAt(0) == '-')
522 ++start;
523 ++point;
524 negative = true;
527 while (point < len)
529 char c = num.charAt (point);
530 if (c == '.')
532 if (dot >= 0)
533 throw new NumberFormatException ("multiple `.'s in number");
534 dot = point;
536 else if (c == 'e' || c == 'E')
537 break;
538 else if (Character.digit (c, 10) < 0)
539 throw new NumberFormatException ("unrecognized character: " + c);
540 ++point;
543 String val;
544 if (dot >= 0)
546 val = num.substring (start, dot) + num.substring (dot + 1, point);
547 scale = point - 1 - dot;
549 else
551 val = num.substring (start, point);
552 scale = 0;
554 if (val.length () == 0)
555 throw new NumberFormatException ("no digits seen");
557 if (negative)
558 val = "-" + val;
559 intVal = new BigInteger (val);
561 // Now parse exponent.
562 if (point < len)
564 point++;
565 if (num.charAt(point) == '+')
566 point++;
568 if (point >= len )
569 throw new NumberFormatException ("no exponent following e or E");
571 try
573 scale -= Integer.parseInt (num.substring (point));
575 catch (NumberFormatException ex)
577 throw new NumberFormatException ("malformed exponent");
582 public static BigDecimal valueOf (long val)
584 return valueOf (val, 0);
587 public static BigDecimal valueOf (long val, int scale)
588 throws NumberFormatException
590 if ((scale == 0) && ((int)val == val))
591 switch ((int) val)
593 case 0:
594 return ZERO;
595 case 1:
596 return ONE;
599 return new BigDecimal (BigInteger.valueOf (val), scale);
602 public BigDecimal add (BigDecimal val)
604 // For addition, need to line up decimals. Note that the movePointRight
605 // method cannot be used for this as it might return a BigDecimal with
606 // scale == 0 instead of the scale we need.
607 BigInteger op1 = intVal;
608 BigInteger op2 = val.intVal;
609 if (scale < val.scale)
610 op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
611 else if (scale > val.scale)
612 op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
614 return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
618 * Returns a BigDecimal whose value is found first by calling the
619 * method add(val) and then by rounding according to the MathContext mc.
620 * @param val the augend
621 * @param mc the MathContext for rounding
622 * @throws ArithmeticException if the value is inexact but the rounding is
623 * RoundingMode.UNNECESSARY
624 * @return <code>this</code> + <code>val</code>, rounded if need be
625 * @since 1.5
627 public BigDecimal add (BigDecimal val, MathContext mc)
629 return add(val).round(mc);
632 public BigDecimal subtract (BigDecimal val)
634 return this.add(val.negate());
638 * Returns a BigDecimal whose value is found first by calling the
639 * method subtract(val) and then by rounding according to the MathContext mc.
640 * @param val the subtrahend
641 * @param mc the MathContext for rounding
642 * @throws ArithmeticException if the value is inexact but the rounding is
643 * RoundingMode.UNNECESSARY
644 * @return <code>this</code> - <code>val</code>, rounded if need be
645 * @since 1.5
647 public BigDecimal subtract (BigDecimal val, MathContext mc)
649 return subtract(val).round(mc);
652 public BigDecimal multiply (BigDecimal val)
654 return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
658 * Returns a BigDecimal whose value is (this x val) before it is rounded
659 * according to the MathContext mc.
660 * @param val the multiplicand
661 * @param mc the MathContext for rounding
662 * @return a new BigDecimal with value approximately (this x val)
663 * @throws ArithmeticException if the value is inexact but the rounding mode
664 * is RoundingMode.UNNECESSARY
665 * @since 1.5
667 public BigDecimal multiply (BigDecimal val, MathContext mc)
669 return multiply(val).round(mc);
672 public BigDecimal divide (BigDecimal val, int roundingMode)
673 throws ArithmeticException, IllegalArgumentException
675 return divide (val, scale, roundingMode);
679 * Returns a BigDecimal whose value is (this / val), with the specified scale
680 * and rounding according to the RoundingMode
681 * @param val the divisor
682 * @param scale the scale of the BigDecimal returned
683 * @param roundingMode the rounding mode to use
684 * @return a BigDecimal whose value is approximately (this / val)
685 * @throws ArithmeticException if divisor is zero or the rounding mode is
686 * UNNECESSARY but the specified scale cannot represent the value exactly
687 * @since 1.5
689 public BigDecimal divide(BigDecimal val,
690 int scale, RoundingMode roundingMode)
692 return divide (val, scale, roundingMode.ordinal());
696 * Returns a BigDecimal whose value is (this / val) rounded according to the
697 * RoundingMode
698 * @param val the divisor
699 * @param roundingMode the rounding mode to use
700 * @return a BigDecimal whose value is approximately (this / val)
701 * @throws ArithmeticException if divisor is zero or the rounding mode is
702 * UNNECESSARY but the specified scale cannot represent the value exactly
704 public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
706 return divide (val, scale, roundingMode.ordinal());
709 public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
710 throws ArithmeticException, IllegalArgumentException
712 if (roundingMode < 0 || roundingMode > 7)
713 throw
714 new IllegalArgumentException("illegal rounding mode: " + roundingMode);
716 if (intVal.signum () == 0) // handle special case of 0.0/0.0
717 return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
719 // Ensure that pow gets a non-negative value.
720 BigInteger valIntVal = val.intVal;
721 int power = newScale - (scale - val.scale);
722 if (power < 0)
724 // Effectively increase the scale of val to avoid an
725 // ArithmeticException for a negative power.
726 valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
727 power = 0;
730 BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
732 BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
734 BigInteger unrounded = parts[0];
735 if (parts[1].signum () == 0) // no remainder, no rounding necessary
736 return new BigDecimal (unrounded, newScale);
738 if (roundingMode == ROUND_UNNECESSARY)
739 throw new ArithmeticException ("Rounding necessary");
741 int sign = intVal.signum () * valIntVal.signum ();
743 if (roundingMode == ROUND_CEILING)
744 roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
745 else if (roundingMode == ROUND_FLOOR)
746 roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
747 else
749 // half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
750 // 1 if >. This implies that the remainder to round is less than,
751 // equal to, or greater than half way to the next digit.
752 BigInteger posRemainder
753 = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
754 valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
755 int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
757 switch(roundingMode)
759 case ROUND_HALF_UP:
760 roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
761 break;
762 case ROUND_HALF_DOWN:
763 roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
764 break;
765 case ROUND_HALF_EVEN:
766 if (half < 0)
767 roundingMode = ROUND_DOWN;
768 else if (half > 0)
769 roundingMode = ROUND_UP;
770 else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
771 roundingMode = ROUND_UP;
772 else // even, ROUND_HALF_DOWN
773 roundingMode = ROUND_DOWN;
774 break;
778 if (roundingMode == ROUND_UP)
779 unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
781 // roundingMode == ROUND_DOWN
782 return new BigDecimal (unrounded, newScale);
786 * Performs division, if the resulting quotient requires rounding
787 * (has a nonterminating decimal expansion),
788 * an ArithmeticException is thrown.
789 * #see divide(BigDecimal, int, int)
790 * @since 1.5
792 public BigDecimal divide(BigDecimal divisor)
793 throws ArithmeticException, IllegalArgumentException
795 return divide(divisor, scale, ROUND_UNNECESSARY);
799 * Returns a BigDecimal whose value is the remainder in the quotient
800 * this / val. This is obtained by
801 * subtract(divideToIntegralValue(val).multiply(val)).
802 * @param val the divisor
803 * @return a BigDecimal whose value is the remainder
804 * @throws ArithmeticException if val == 0
805 * @since 1.5
807 public BigDecimal remainder(BigDecimal val)
809 return subtract(divideToIntegralValue(val).multiply(val));
813 * Returns a BigDecimal array, the first element of which is the integer part
814 * of this / val, and the second element of which is the remainder of
815 * that quotient.
816 * @param val the divisor
817 * @return the above described BigDecimal array
818 * @throws ArithmeticException if val == 0
819 * @since 1.5
821 public BigDecimal[] divideAndRemainder(BigDecimal val)
823 BigDecimal[] result = new BigDecimal[2];
824 result[0] = divideToIntegralValue(val);
825 result[1] = subtract(result[0].multiply(val));
826 return result;
830 * Returns a BigDecimal whose value is the integer part of the quotient
831 * this / val. The preferred scale is this.scale - val.scale.
832 * @param val the divisor
833 * @return a BigDecimal whose value is the integer part of this / val.
834 * @throws ArithmeticException if val == 0
835 * @since 1.5
837 public BigDecimal divideToIntegralValue(BigDecimal val)
839 return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
843 * Mutates this BigDecimal into one with no fractional part, whose value is
844 * equal to the largest integer that is <= to this BigDecimal. Note that
845 * since this method is private it is okay to mutate this BigDecimal.
846 * @return the BigDecimal obtained through the floor operation on this
847 * BigDecimal.
849 private BigDecimal floor()
851 if (scale <= 0)
852 return this;
853 String intValStr = intVal.toString();
854 intValStr = intValStr.substring(0, intValStr.length() - scale);
855 intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
856 return this;
859 public int compareTo (BigDecimal val)
861 if (scale == val.scale)
862 return intVal.compareTo (val.intVal);
864 BigInteger thisParts[] =
865 intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
866 BigInteger valParts[] =
867 val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
869 int compare;
870 if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
871 return compare;
873 // quotients are the same, so compare remainders
875 // Add some trailing zeros to the remainder with the smallest scale
876 if (scale < val.scale)
877 thisParts[1] = thisParts[1].multiply
878 (BigInteger.valueOf (10).pow (val.scale - scale));
879 else if (scale > val.scale)
880 valParts[1] = valParts[1].multiply
881 (BigInteger.valueOf (10).pow (scale - val.scale));
883 // and compare them
884 return thisParts[1].compareTo (valParts[1]);
887 public boolean equals (Object o)
889 return (o instanceof BigDecimal
890 && scale == ((BigDecimal) o).scale
891 && compareTo ((BigDecimal) o) == 0);
894 public int hashCode()
896 return intValue() ^ scale;
899 public BigDecimal max (BigDecimal val)
901 switch (compareTo (val))
903 case 1:
904 return this;
905 default:
906 return val;
910 public BigDecimal min (BigDecimal val)
912 switch (compareTo (val))
914 case -1:
915 return this;
916 default:
917 return val;
921 public BigDecimal movePointLeft (int n)
923 return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
926 public BigDecimal movePointRight (int n)
928 if (n < 0)
929 return movePointLeft (-n);
931 if (scale >= n)
932 return new BigDecimal (intVal, scale - n);
934 return new BigDecimal (intVal.multiply
935 (BigInteger.TEN.pow (n - scale)), 0);
938 public int signum ()
940 return intVal.signum ();
943 public int scale ()
945 return scale;
948 public BigInteger unscaledValue()
950 return intVal;
953 public BigDecimal abs ()
955 return new BigDecimal (intVal.abs (), scale);
958 public BigDecimal negate ()
960 return new BigDecimal (intVal.negate (), scale);
964 * Returns a BigDecimal whose value is found first by negating this via
965 * the negate() method, then by rounding according to the MathContext mc.
966 * @param mc the MathContext for rounding
967 * @return a BigDecimal whose value is approximately (-this)
968 * @throws ArithmeticException if the value is inexact but the rounding mode
969 * is RoundingMode.UNNECESSARY
970 * @since 1.5
972 public BigDecimal negate(MathContext mc)
974 BigDecimal result = negate();
975 if (mc.getPrecision() != 0)
976 result = result.round(mc);
977 return result;
981 * Returns this BigDecimal. This is included for symmetry with the
982 * method negate().
983 * @return this
984 * @since 1.5
986 public BigDecimal plus()
988 return this;
992 * Returns a BigDecimal whose value is found by rounding <code>this</code>
993 * according to the MathContext. This is the same as round(MathContext).
994 * @param mc the MathContext for rounding
995 * @return a BigDecimal whose value is <code>this</code> before being rounded
996 * @throws ArithmeticException if the value is inexact but the rounding mode
997 * is RoundingMode.UNNECESSARY
998 * @since 1.5
1000 public BigDecimal plus(MathContext mc)
1002 return round(mc);
1006 * Returns a BigDecimal which is this BigDecimal rounded according to the
1007 * MathContext rounding settings.
1008 * @param mc the MathContext that tells us how to round
1009 * @return the rounded BigDecimal
1011 public BigDecimal round(MathContext mc)
1013 int mcPrecision = mc.getPrecision();
1014 int numToChop = precision() - mcPrecision;
1015 // If mc specifies not to chop any digits or if we've already chopped
1016 // enough digits (say by using a MathContext in the constructor for this
1017 // BigDecimal) then just return this.
1018 if (mcPrecision == 0 || numToChop <= 0)
1019 return this;
1021 // Make a new BigDecimal which is the correct power of 10 to chop off
1022 // the required number of digits and then call divide.
1023 BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
1024 BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
1025 rounded.scale -= numToChop;
1026 rounded.precision = mcPrecision;
1027 return rounded;
1031 * Returns the precision of this BigDecimal (the number of digits in the
1032 * unscaled value). The precision of a zero value is 1.
1033 * @return the number of digits in the unscaled value, or 1 if the value
1034 * is zero.
1036 public int precision()
1038 if (precision == 0)
1040 String s = intVal.toString();
1041 precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1043 return precision;
1047 * Returns the String representation of this BigDecimal, using scientific
1048 * notation if necessary. The following steps are taken to generate
1049 * the result:
1051 * 1. the BigInteger unscaledValue's toString method is called and if
1052 * <code>scale == 0<code> is returned.
1053 * 2. an <code>int adjExp</code> is created which is equal to the negation
1054 * of <code>scale</code> plus the number of digits in the unscaled value,
1055 * minus one.
1056 * 3. if <code>scale >= 0 && adjExp >= -6</code> then we represent this
1057 * BigDecimal without scientific notation. A decimal is added if the
1058 * scale is positive and zeros are prepended as necessary.
1059 * 4. if scale is negative or adjExp is less than -6 we use scientific
1060 * notation. If the unscaled value has more than one digit, a decimal
1061 * as inserted after the first digit, the character 'E' is appended
1062 * and adjExp is appended.
1064 public String toString()
1066 // bigStr is the String representation of the unscaled value. If
1067 // scale is zero we simply return this.
1068 String bigStr = intVal.toString();
1069 if (scale == 0)
1070 return bigStr;
1072 boolean negative = (bigStr.charAt(0) == '-');
1073 int point = bigStr.length() - scale - (negative ? 1 : 0);
1075 CPStringBuilder val = new CPStringBuilder();
1077 if (scale >= 0 && (point - 1) >= -6)
1079 // Convert to character form without scientific notation.
1080 if (point <= 0)
1082 // Zeros need to be prepended to the StringBuilder.
1083 if (negative)
1084 val.append('-');
1085 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1086 val.append('0').append('.');
1087 while (point < 0)
1089 val.append('0');
1090 point++;
1092 // Append the unscaled value.
1093 val.append(bigStr.substring(negative ? 1 : 0));
1095 else
1097 // No zeros need to be prepended so the String is simply the
1098 // unscaled value with the decimal point inserted.
1099 val.append(bigStr);
1100 val.insert(point + (negative ? 1 : 0), '.');
1103 else
1105 // We must use scientific notation to represent this BigDecimal.
1106 val.append(bigStr);
1107 // If there is more than one digit in the unscaled value we put a
1108 // decimal after the first digit.
1109 if (bigStr.length() > 1)
1110 val.insert( ( negative ? 2 : 1 ), '.');
1111 // And then append 'E' and the exponent = (point - 1).
1112 val.append('E');
1113 if (point - 1 >= 0)
1114 val.append('+');
1115 val.append( point - 1 );
1117 return val.toString();
1121 * Returns the String representation of this BigDecimal, using engineering
1122 * notation if necessary. This is similar to toString() but when exponents
1123 * are used the exponent is made to be a multiple of 3 such that the integer
1124 * part is between 1 and 999.
1126 * @return a String representation of this BigDecimal in engineering notation
1127 * @since 1.5
1129 public String toEngineeringString()
1131 // bigStr is the String representation of the unscaled value. If
1132 // scale is zero we simply return this.
1133 String bigStr = intVal.toString();
1134 if (scale == 0)
1135 return bigStr;
1137 boolean negative = (bigStr.charAt(0) == '-');
1138 int point = bigStr.length() - scale - (negative ? 1 : 0);
1140 // This is the adjusted exponent described above.
1141 int adjExp = point - 1;
1142 CPStringBuilder val = new CPStringBuilder();
1144 if (scale >= 0 && adjExp >= -6)
1146 // Convert to character form without scientific notation.
1147 if (point <= 0)
1149 // Zeros need to be prepended to the StringBuilder.
1150 if (negative)
1151 val.append('-');
1152 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1153 val.append('0').append('.');
1154 while (point < 0)
1156 val.append('0');
1157 point++;
1159 // Append the unscaled value.
1160 val.append(bigStr.substring(negative ? 1 : 0));
1162 else
1164 // No zeros need to be prepended so the String is simply the
1165 // unscaled value with the decimal point inserted.
1166 val.append(bigStr);
1167 val.insert(point + (negative ? 1 : 0), '.');
1170 else
1172 // We must use scientific notation to represent this BigDecimal.
1173 // The exponent must be a multiple of 3 and the integer part
1174 // must be between 1 and 999.
1175 val.append(bigStr);
1176 int zeros = adjExp % 3;
1177 int dot = 1;
1178 if (adjExp > 0)
1180 // If the exponent is positive we just move the decimal to the
1181 // right and decrease the exponent until it is a multiple of 3.
1182 dot += zeros;
1183 adjExp -= zeros;
1185 else
1187 // If the exponent is negative then we move the dot to the right
1188 // and decrease the exponent (increase its magnitude) until
1189 // it is a multiple of 3. Note that this is not adjExp -= zeros
1190 // because the mod operator doesn't give us the distance to the
1191 // correct multiple of 3. (-5 mod 3) is -2 but the distance from
1192 // -5 to the correct multiple of 3 (-6) is 1, not 2.
1193 if (zeros == -2)
1195 dot += 1;
1196 adjExp -= 1;
1198 else if (zeros == -1)
1200 dot += 2;
1201 adjExp -= 2;
1205 // Either we have to append zeros because, for example, 1.1E+5 should
1206 // be 110E+3, or we just have to put the decimal in the right place.
1207 if (dot > val.length())
1209 while (dot > val.length())
1210 val.append('0');
1212 else if (bigStr.length() > dot)
1213 val.insert(dot + (negative ? 1 : 0), '.');
1215 // And then append 'E' and the exponent (adjExp).
1216 val.append('E');
1217 if (adjExp >= 0)
1218 val.append('+');
1219 val.append(adjExp);
1221 return val.toString();
1225 * Returns a String representation of this BigDecimal without using
1226 * scientific notation. This is how toString() worked for releases 1.4
1227 * and previous. Zeros may be added to the end of the String. For
1228 * example, an unscaled value of 1234 and a scale of -3 would result in
1229 * the String 1234000, but the toString() method would return
1230 * 1.234E+6.
1231 * @return a String representation of this BigDecimal
1232 * @since 1.5
1234 public String toPlainString()
1236 // If the scale is zero we simply return the String representation of the
1237 // unscaled value.
1238 String bigStr = intVal.toString();
1239 if (scale == 0)
1240 return bigStr;
1242 // Remember if we have to put a negative sign at the start.
1243 boolean negative = (bigStr.charAt(0) == '-');
1245 int point = bigStr.length() - scale - (negative ? 1 : 0);
1247 CPStringBuilder sb = new CPStringBuilder(bigStr.length() + 2
1248 + (point <= 0 ? (-point + 1) : 0));
1249 if (point <= 0)
1251 // We have to prepend zeros and a decimal point.
1252 if (negative)
1253 sb.append('-');
1254 sb.append('0').append('.');
1255 while (point < 0)
1257 sb.append('0');
1258 point++;
1260 sb.append(bigStr.substring(negative ? 1 : 0));
1262 else if (point < bigStr.length())
1264 // No zeros need to be prepended or appended, just put the decimal
1265 // in the right place.
1266 sb.append(bigStr);
1267 sb.insert(point + (negative ? 1 : 0), '.');
1269 else
1271 // We must append zeros instead of using scientific notation.
1272 sb.append(bigStr);
1273 for (int i = bigStr.length(); i < point; i++)
1274 sb.append('0');
1276 return sb.toString();
1280 * Converts this BigDecimal to a BigInteger. Any fractional part will
1281 * be discarded.
1282 * @return a BigDecimal whose value is equal to floor[this]
1284 public BigInteger toBigInteger ()
1286 // If scale > 0 then we must divide, if scale > 0 then we must multiply,
1287 // and if scale is zero then we just return intVal;
1288 if (scale > 0)
1289 return intVal.divide (BigInteger.TEN.pow (scale));
1290 else if (scale < 0)
1291 return intVal.multiply(BigInteger.TEN.pow(-scale));
1292 return intVal;
1296 * Converts this BigDecimal into a BigInteger, throwing an
1297 * ArithmeticException if the conversion is not exact.
1298 * @return a BigInteger whose value is equal to the value of this BigDecimal
1299 * @since 1.5
1301 public BigInteger toBigIntegerExact()
1303 if (scale > 0)
1305 // If we have to divide, we must check if the result is exact.
1306 BigInteger[] result =
1307 intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
1308 if (result[1].equals(BigInteger.ZERO))
1309 return result[0];
1310 throw new ArithmeticException("No exact BigInteger representation");
1312 else if (scale < 0)
1313 // If we're multiplying instead, then we needn't check for exactness.
1314 return intVal.multiply(BigInteger.TEN.pow(-scale));
1315 // If the scale is zero we can simply return intVal.
1316 return intVal;
1319 public int intValue ()
1321 return toBigInteger ().intValue ();
1325 * Returns a BigDecimal which is numerically equal to this BigDecimal but
1326 * with no trailing zeros in the representation. For example, if this
1327 * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns
1328 * a BigDecimal with [unscaledValue, scale] = [6313, 1]. As another
1329 * example, [12400, -2] would become [124, -4].
1330 * @return a numerically equal BigDecimal with no trailing zeros
1332 public BigDecimal stripTrailingZeros()
1334 String intValStr = intVal.toString();
1335 int newScale = scale;
1336 int pointer = intValStr.length() - 1;
1337 // This loop adjusts pointer which will be used to give us the substring
1338 // of intValStr to use in our new BigDecimal, and also accordingly
1339 // adjusts the scale of our new BigDecimal.
1340 while (intValStr.charAt(pointer) == '0')
1342 pointer --;
1343 newScale --;
1345 // Create a new BigDecimal with the appropriate substring and then
1346 // set its scale.
1347 BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
1348 result.scale = newScale;
1349 return result;
1352 public long longValue ()
1354 return toBigInteger().longValue();
1357 public float floatValue()
1359 return Float.valueOf(toString()).floatValue();
1362 public double doubleValue()
1364 return Double.valueOf(toString()).doubleValue();
1367 public BigDecimal setScale (int scale) throws ArithmeticException
1369 return setScale (scale, ROUND_UNNECESSARY);
1372 public BigDecimal setScale (int scale, int roundingMode)
1373 throws ArithmeticException, IllegalArgumentException
1375 // NOTE: The 1.5 JRE doesn't throw this, ones prior to it do and
1376 // the spec says it should. Nevertheless, if 1.6 doesn't fix this
1377 // we should consider removing it.
1378 if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
1379 return divide (ONE, scale, roundingMode);
1383 * Returns a BigDecimal whose value is the same as this BigDecimal but whose
1384 * representation has a scale of <code>newScale</code>. If the scale is
1385 * reduced then rounding may occur, according to the RoundingMode.
1386 * @param newScale
1387 * @param roundingMode
1388 * @return a BigDecimal whose scale is as given, whose value is
1389 * <code>this</code> with possible rounding
1390 * @throws ArithmeticException if the rounding mode is UNNECESSARY but
1391 * rounding is required
1392 * @since 1.5
1394 public BigDecimal setScale(int newScale, RoundingMode roundingMode)
1396 return setScale(newScale, roundingMode.ordinal());
1400 * Returns a new BigDecimal constructed from the BigDecimal(String)
1401 * constructor using the Double.toString(double) method to obtain
1402 * the String.
1403 * @param val the double value used in Double.toString(double)
1404 * @return a BigDecimal representation of val
1405 * @throws NumberFormatException if val is NaN or infinite
1406 * @since 1.5
1408 public static BigDecimal valueOf(double val)
1410 if (Double.isInfinite(val) || Double.isNaN(val))
1411 throw new NumberFormatException("argument cannot be NaN or infinite.");
1412 return new BigDecimal(Double.toString(val));
1416 * Returns a BigDecimal whose numerical value is the numerical value
1417 * of this BigDecimal multiplied by 10 to the power of <code>n</code>.
1418 * @param n the power of ten
1419 * @return the new BigDecimal
1420 * @since 1.5
1422 public BigDecimal scaleByPowerOfTen(int n)
1424 BigDecimal result = new BigDecimal(intVal, scale - n);
1425 result.precision = precision;
1426 return result;
1430 * Returns a BigDecimal whose value is <code>this</code> to the power of
1431 * <code>n</code>.
1432 * @param n the power
1433 * @return the new BigDecimal
1434 * @since 1.5
1436 public BigDecimal pow(int n)
1438 if (n < 0 || n > 999999999)
1439 throw new ArithmeticException("n must be between 0 and 999999999");
1440 BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
1441 return result;
1445 * Returns a BigDecimal whose value is determined by first calling pow(n)
1446 * and then by rounding according to the MathContext mc.
1447 * @param n the power
1448 * @param mc the MathContext
1449 * @return the new BigDecimal
1450 * @throws ArithmeticException if n < 0 or n > 999999999 or if the result is
1451 * inexact but the rounding is RoundingMode.UNNECESSARY
1452 * @since 1.5
1454 public BigDecimal pow(int n, MathContext mc)
1456 // FIXME: The specs claim to use the X3.274-1996 algorithm. We
1457 // currently do not.
1458 return pow(n).round(mc);
1462 * Returns a BigDecimal whose value is the absolute value of this BigDecimal
1463 * with rounding according to the given MathContext.
1464 * @param mc the MathContext
1465 * @return the new BigDecimal
1467 public BigDecimal abs(MathContext mc)
1469 BigDecimal result = abs();
1470 result = result.round(mc);
1471 return result;
1475 * Returns the size of a unit in the last place of this BigDecimal. This
1476 * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()].
1477 * @return the size of a unit in the last place of <code>this</code>.
1478 * @since 1.5
1480 public BigDecimal ulp()
1482 return new BigDecimal(BigInteger.ONE, scale);
1486 * Converts this BigDecimal to a long value.
1487 * @return the long value
1488 * @throws ArithmeticException if rounding occurs or if overflow occurs
1489 * @since 1.5
1491 public long longValueExact()
1493 // Set scale will throw an exception if rounding occurs.
1494 BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
1495 BigInteger tempVal = temp.intVal;
1496 // Check for overflow.
1497 long result = intVal.longValue();
1498 if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
1499 || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
1500 throw new ArithmeticException("this BigDecimal is too " +
1501 "large to fit into the return type");
1503 return intVal.longValue();
1507 * Converts this BigDecimal into an int by first calling longValueExact
1508 * and then checking that the <code>long</code> returned from that
1509 * method fits into an <code>int</code>.
1510 * @return an int whose value is <code>this</code>
1511 * @throws ArithmeticException if this BigDecimal has a fractional part
1512 * or is too large to fit into an int.
1513 * @since 1.5
1515 public int intValueExact()
1517 long temp = longValueExact();
1518 int result = (int)temp;
1519 if (result != temp)
1520 throw new ArithmeticException ("this BigDecimal cannot fit into an int");
1521 return result;
1525 * Converts this BigDecimal into a byte by first calling longValueExact
1526 * and then checking that the <code>long</code> returned from that
1527 * method fits into a <code>byte</code>.
1528 * @return a byte whose value is <code>this</code>
1529 * @throws ArithmeticException if this BigDecimal has a fractional part
1530 * or is too large to fit into a byte.
1531 * @since 1.5
1533 public byte byteValueExact()
1535 long temp = longValueExact();
1536 byte result = (byte)temp;
1537 if (result != temp)
1538 throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
1539 return result;
1543 * Converts this BigDecimal into a short by first calling longValueExact
1544 * and then checking that the <code>long</code> returned from that
1545 * method fits into a <code>short</code>.
1546 * @return a short whose value is <code>this</code>
1547 * @throws ArithmeticException if this BigDecimal has a fractional part
1548 * or is too large to fit into a short.
1549 * @since 1.5
1551 public short shortValueExact()
1553 long temp = longValueExact();
1554 short result = (short)temp;
1555 if (result != temp)
1556 throw new ArithmeticException ("this BigDecimal cannot fit into a short");
1557 return result;