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)
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
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
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. */
40 public class BigDecimal extends Number implements Comparable<BigDecimal>
42 private BigInteger intVal;
44 private int precision = 0;
45 private static final long serialVersionUID = 6108874887143696463L;
48 * The constant zero as a BigDecimal with scale zero.
51 public static final BigDecimal ZERO =
52 new BigDecimal (BigInteger.ZERO, 0);
55 * The constant one as a BigDecimal with scale zero.
58 public static final BigDecimal ONE =
59 new BigDecimal (BigInteger.ONE, 0);
62 * The constant ten as a BigDecimal with scale zero.
65 public static final BigDecimal TEN =
66 new BigDecimal (BigInteger.TEN, 0);
68 public static final int ROUND_UP = 0;
69 public static final int ROUND_DOWN = 1;
70 public static final int ROUND_CEILING = 2;
71 public static final int ROUND_FLOOR = 3;
72 public static final int ROUND_HALF_UP = 4;
73 public static final int ROUND_HALF_DOWN = 5;
74 public static final int ROUND_HALF_EVEN = 6;
75 public static final int ROUND_UNNECESSARY = 7;
78 * Constructs a new BigDecimal whose unscaled value is val and whose
80 * @param val the value of the new BigDecimal
83 public BigDecimal (int val)
85 this.intVal = BigInteger.valueOf(val);
90 * Constructs a BigDecimal using the BigDecimal(int) constructor and then
91 * rounds according to the MathContext.
92 * @param val the value for the initial (unrounded) BigDecimal
93 * @param mc the MathContext specifying the rounding
94 * @throws ArithmeticException if the result is inexact but the rounding type
95 * is RoundingMode.UNNECESSARY
98 public BigDecimal (int val, MathContext mc)
101 if (mc.getPrecision() != 0)
103 BigDecimal result = this.round(mc);
104 this.intVal = result.intVal;
105 this.scale = result.scale;
106 this.precision = result.precision;
111 * Constructs a new BigDecimal whose unscaled value is val and whose
113 * @param val the value of the new BigDecimal
115 public BigDecimal (long val)
117 this.intVal = BigInteger.valueOf(val);
122 * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
123 * and then rounds according to the MathContext.
124 * @param val the long from which we create the initial BigDecimal
125 * @param mc the MathContext that specifies the rounding behaviour
126 * @throws ArithmeticException if the result is inexact but the rounding type
127 * is RoundingMode.UNNECESSARY
130 public BigDecimal (long val, MathContext mc)
133 if (mc.getPrecision() != 0)
135 BigDecimal result = this.round(mc);
136 this.intVal = result.intVal;
137 this.scale = result.scale;
138 this.precision = result.precision;
143 * Constructs a BigDecimal whose value is given by num rounded according to
144 * mc. Since num is already a BigInteger, the rounding refers only to the
145 * precision setting in mc, if mc.getPrecision() returns an int lower than
146 * the number of digits in num, then rounding is necessary.
147 * @param num the unscaledValue, before rounding
148 * @param mc the MathContext that specifies the precision
149 * @throws ArithmeticException if the result is inexact but the rounding type
150 * is RoundingMode.UNNECESSARY
153 public BigDecimal (BigInteger num, MathContext mc)
156 if (mc.getPrecision() != 0)
158 BigDecimal result = this.round(mc);
159 this.intVal = result.intVal;
160 this.scale = result.scale;
161 this.precision = result.precision;
166 * Constructs a BigDecimal from the String val according to the same
167 * rules as the BigDecimal(String) constructor and then rounds
168 * according to the MathContext mc.
169 * @param val the String from which we construct the initial BigDecimal
170 * @param mc the MathContext that specifies the rounding
171 * @throws ArithmeticException if the result is inexact but the rounding type
172 * is RoundingMode.UNNECESSARY
175 public BigDecimal (String val, MathContext mc)
178 if (mc.getPrecision() != 0)
180 BigDecimal result = this.round(mc);
181 this.intVal = result.intVal;
182 this.scale = result.scale;
183 this.precision = result.precision;
188 * Constructs a BigDecimal whose unscaled value is num and whose
190 * @param num the value of the new BigDecimal
192 public BigDecimal (BigInteger num)
198 * Constructs a BigDecimal whose unscaled value is num and whose
203 public BigDecimal (BigInteger num, int scale)
210 * Constructs a BigDecimal using the BigDecimal(BigInteger, int)
211 * constructor and then rounds according to the MathContext.
212 * @param num the unscaled value of the unrounded BigDecimal
213 * @param scale the scale of the unrounded BigDecimal
214 * @param mc the MathContext specifying the rounding
215 * @throws ArithmeticException if the result is inexact but the rounding type
216 * is RoundingMode.UNNECESSARY
219 public BigDecimal (BigInteger num, int scale, MathContext mc)
222 if (mc.getPrecision() != 0)
224 BigDecimal result = this.round(mc);
225 this.intVal = result.intVal;
226 this.scale = result.scale;
227 this.precision = result.precision;
232 * Constructs a BigDecimal in the same way as BigDecimal(double) and then
233 * rounds according to the MathContext.
234 * @param num the double from which the initial BigDecimal is created
235 * @param mc the MathContext that specifies the rounding behaviour
236 * @throws ArithmeticException if the result is inexact but the rounding type
237 * is RoundingMode.UNNECESSARY
240 public BigDecimal (double num, MathContext mc)
243 if (mc.getPrecision() != 0)
245 BigDecimal result = this.round(mc);
246 this.intVal = result.intVal;
247 this.scale = result.scale;
248 this.precision = result.precision;
252 public BigDecimal (double num) throws NumberFormatException
254 if (Double.isInfinite (num) || Double.isNaN (num))
255 throw new NumberFormatException ("invalid argument: " + num);
256 // Note we can't convert NUM to a String and then use the
257 // String-based constructor. The BigDecimal documentation makes
258 // it clear that the two constructors work differently.
260 final int mantissaBits = 52;
261 final int exponentBits = 11;
262 final long mantMask = (1L << mantissaBits) - 1;
263 final long expMask = (1L << exponentBits) - 1;
265 long bits = Double.doubleToLongBits (num);
266 long mantissa = bits & mantMask;
267 long exponent = (bits >>> mantissaBits) & expMask;
268 boolean denormal = exponent == 0;
270 // Correct the exponent for the bias.
271 exponent -= denormal ? 1022 : 1023;
273 // Now correct the exponent to account for the bits to the right
275 exponent -= mantissaBits;
276 // Ordinary numbers have an implied leading `1' bit.
278 mantissa |= (1L << mantissaBits);
280 // Shave off factors of 10.
281 while (exponent < 0 && (mantissa & 1) == 0)
287 intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
290 // We have MANTISSA * 2 ^ (EXPONENT).
291 // Since (1/2)^N == 5^N * 10^-N we can easily convert this
292 // into a power of 10.
293 scale = (int) (- exponent);
294 BigInteger mult = BigInteger.valueOf (5).pow (scale);
295 intVal = intVal.multiply (mult);
299 intVal = intVal.shiftLeft ((int) exponent);
305 * Constructs a BigDecimal from the char subarray and rounding
306 * according to the MathContext.
307 * @param in the char array
308 * @param offset the start of the subarray
309 * @param len the length of the subarray
310 * @param mc the MathContext for rounding
311 * @throws NumberFormatException if the char subarray is not a valid
312 * BigDecimal representation
313 * @throws ArithmeticException if the result is inexact but the rounding
314 * mode is RoundingMode.UNNECESSARY
317 public BigDecimal(char[] in, int offset, int len, MathContext mc)
319 this(in, offset, len);
320 // If mc has precision other than zero then we must round.
321 if (mc.getPrecision() != 0)
323 BigDecimal temp = this.round(mc);
324 this.intVal = temp.intVal;
325 this.scale = temp.scale;
326 this.precision = temp.precision;
331 * Constructs a BigDecimal from the char array and rounding according
332 * to the MathContext.
333 * @param in the char array
334 * @param mc the MathContext
335 * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
337 * @throws ArithmeticException if the result is inexact but the rounding mode
338 * is RoundingMode.UNNECESSARY
341 public BigDecimal(char[] in, MathContext mc)
343 this(in, 0, in.length);
344 // If mc has precision other than zero then we must round.
345 if (mc.getPrecision() != 0)
347 BigDecimal temp = this.round(mc);
348 this.intVal = temp.intVal;
349 this.scale = temp.scale;
350 this.precision = temp.precision;
355 * Constructs a BigDecimal from the given char array, accepting the same
356 * sequence of characters as the BigDecimal(String) constructor.
357 * @param in the char array
358 * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
362 public BigDecimal(char[] in)
364 this(in, 0, in.length);
368 * Constructs a BigDecimal from a char subarray, accepting the same sequence
369 * of characters as the BigDecimal(String) constructor.
370 * @param in the char array
371 * @param offset the start of the subarray
372 * @param len the length of the subarray
373 * @throws NumberFormatException if <code>in</code> is not a valid
374 * BigDecimal representation.
377 public BigDecimal(char[] in, int offset, int len)
379 // start is the index into the char array where the significand starts
381 // end is one greater than the index of the last character used
382 int end = offset + len;
383 // point is the index into the char array where the exponent starts
384 // (or, if there is no exponent, this is equal to end)
386 // dot is the index into the char array where the decimal point is
387 // found, or -1 if there is no decimal point
390 // The following examples show what these variables mean. Note that
391 // point and dot don't yet have the correct values, they will be
392 // properly assigned in a loop later on in this method.
397 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
399 // offset = 2, len = 8, start = 3, dot = 6, point = end = 10
403 // + 2 3 4 . 6 1 3 E - 1
404 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
406 // offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
411 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
413 // offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
415 // Determine the sign of the number.
416 boolean negative = false;
417 if (in[offset] == '+')
422 else if (in[offset] == '-')
429 // Check each character looking for the decimal point and the
430 // start of the exponent.
436 // If dot != -1 then we've seen more than one decimal point.
438 throw new NumberFormatException("multiple `.'s in number");
441 // Break when we reach the start of the exponent.
442 else if (c == 'e' || c == 'E')
444 // Throw an exception if the character was not a decimal or an
445 // exponent and is not a digit.
446 else if (!Character.isDigit(c))
447 throw new NumberFormatException("unrecognized character at " + point
452 // val is a StringBuilder from which we'll create a BigInteger
453 // which will be the unscaled value for this BigDecimal
454 StringBuilder val = new StringBuilder(point - start - 1);
457 // If there was a decimal we must combine the two parts that
458 // contain only digits and we must set the scale properly.
459 val.append(in, start, dot - start);
460 val.append(in, dot + 1, point - dot - 1);
461 scale = point - 1 - dot;
465 // If there was no decimal then the unscaled value is just the number
466 // formed from all the digits and the scale is zero.
467 val.append(in, start, point - start);
470 if (val.length() == 0)
471 throw new NumberFormatException("no digits seen");
473 // Prepend a negative sign if necessary.
476 intVal = new BigInteger(val.toString());
478 // Now parse exponent.
479 // If point < end that means we broke out of the previous loop when we
480 // saw an 'e' or an 'E'.
484 // Ignore a '+' sign.
485 if (in[point] == '+')
488 // Throw an exception if there were no digits found after the 'e'
491 throw new NumberFormatException("no exponent following e or E");
495 // Adjust the scale according to the exponent.
496 // Remember that the value of a BigDecimal is
497 // unscaledValue x Math.pow(10, -scale)
498 scale -= Integer.parseInt(new String(in, point, end - point));
500 catch (NumberFormatException ex)
502 throw new NumberFormatException("malformed exponent");
507 public BigDecimal (String num) throws NumberFormatException
509 int len = num.length();
510 int start = 0, point = 0;
512 boolean negative = false;
513 if (num.charAt(0) == '+')
518 else if (num.charAt(0) == '-')
527 char c = num.charAt (point);
531 throw new NumberFormatException ("multiple `.'s in number");
534 else if (c == 'e' || c == 'E')
536 else if (Character.digit (c, 10) < 0)
537 throw new NumberFormatException ("unrecognized character: " + c);
544 val = num.substring (start, dot) + num.substring (dot + 1, point);
545 scale = point - 1 - dot;
549 val = num.substring (start, point);
552 if (val.length () == 0)
553 throw new NumberFormatException ("no digits seen");
557 intVal = new BigInteger (val);
559 // Now parse exponent.
563 if (num.charAt(point) == '+')
567 throw new NumberFormatException ("no exponent following e or E");
571 scale -= Integer.parseInt (num.substring (point));
573 catch (NumberFormatException ex)
575 throw new NumberFormatException ("malformed exponent");
580 public static BigDecimal valueOf (long val)
582 return valueOf (val, 0);
585 public static BigDecimal valueOf (long val, int scale)
586 throws NumberFormatException
588 if ((scale == 0) && ((int)val == val))
597 return new BigDecimal (BigInteger.valueOf (val), scale);
600 public BigDecimal add (BigDecimal val)
602 // For addition, need to line up decimals. Note that the movePointRight
603 // method cannot be used for this as it might return a BigDecimal with
604 // scale == 0 instead of the scale we need.
605 BigInteger op1 = intVal;
606 BigInteger op2 = val.intVal;
607 if (scale < val.scale)
608 op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
609 else if (scale > val.scale)
610 op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
612 return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
616 * Returns a BigDecimal whose value is found first by calling the
617 * method add(val) and then by rounding according to the MathContext mc.
618 * @param val the augend
619 * @param mc the MathContext for rounding
620 * @throws ArithmeticException if the value is inexact but the rounding is
621 * RoundingMode.UNNECESSARY
622 * @return <code>this</code> + <code>val</code>, rounded if need be
625 public BigDecimal add (BigDecimal val, MathContext mc)
627 return add(val).round(mc);
630 public BigDecimal subtract (BigDecimal val)
632 return this.add(val.negate());
636 * Returns a BigDecimal whose value is found first by calling the
637 * method subtract(val) and then by rounding according to the MathContext mc.
638 * @param val the subtrahend
639 * @param mc the MathContext for rounding
640 * @throws ArithmeticException if the value is inexact but the rounding is
641 * RoundingMode.UNNECESSARY
642 * @return <code>this</code> - <code>val</code>, rounded if need be
645 public BigDecimal subtract (BigDecimal val, MathContext mc)
647 return subtract(val).round(mc);
650 public BigDecimal multiply (BigDecimal val)
652 return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
656 * Returns a BigDecimal whose value is (this x val) before it is rounded
657 * according to the MathContext mc.
658 * @param val the multiplicand
659 * @param mc the MathContext for rounding
660 * @return a new BigDecimal with value approximately (this x val)
661 * @throws ArithmeticException if the value is inexact but the rounding mode
662 * is RoundingMode.UNNECESSARY
665 public BigDecimal multiply (BigDecimal val, MathContext mc)
667 return multiply(val).round(mc);
670 public BigDecimal divide (BigDecimal val, int roundingMode)
671 throws ArithmeticException, IllegalArgumentException
673 return divide (val, scale, roundingMode);
677 * Returns a BigDecimal whose value is (this / val), with the specified scale
678 * and rounding according to the RoundingMode
679 * @param val the divisor
680 * @param scale the scale of the BigDecimal returned
681 * @param roundingMode the rounding mode to use
682 * @return a BigDecimal whose value is approximately (this / val)
683 * @throws ArithmeticException if divisor is zero or the rounding mode is
684 * UNNECESSARY but the specified scale cannot represent the value exactly
687 public BigDecimal divide(BigDecimal val,
688 int scale, RoundingMode roundingMode)
690 return divide (val, scale, roundingMode.ordinal());
694 * Returns a BigDecimal whose value is (this / val) rounded according to the
696 * @param val the divisor
697 * @param roundingMode the rounding mode to use
698 * @return a BigDecimal whose value is approximately (this / val)
699 * @throws ArithmeticException if divisor is zero or the rounding mode is
700 * UNNECESSARY but the specified scale cannot represent the value exactly
702 public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
704 return divide (val, scale, roundingMode.ordinal());
707 public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
708 throws ArithmeticException, IllegalArgumentException
710 if (roundingMode < 0 || roundingMode > 7)
712 new IllegalArgumentException("illegal rounding mode: " + roundingMode);
714 if (intVal.signum () == 0) // handle special case of 0.0/0.0
715 return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
717 // Ensure that pow gets a non-negative value.
718 BigInteger valIntVal = val.intVal;
719 int power = newScale - (scale - val.scale);
722 // Effectively increase the scale of val to avoid an
723 // ArithmeticException for a negative power.
724 valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
728 BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
730 BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
732 BigInteger unrounded = parts[0];
733 if (parts[1].signum () == 0) // no remainder, no rounding necessary
734 return new BigDecimal (unrounded, newScale);
736 if (roundingMode == ROUND_UNNECESSARY)
737 throw new ArithmeticException ("Rounding necessary");
739 int sign = intVal.signum () * valIntVal.signum ();
741 if (roundingMode == ROUND_CEILING)
742 roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
743 else if (roundingMode == ROUND_FLOOR)
744 roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
747 // half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
748 // 1 if >. This implies that the remainder to round is less than,
749 // equal to, or greater than half way to the next digit.
750 BigInteger posRemainder
751 = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
752 valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
753 int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
758 roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
760 case ROUND_HALF_DOWN:
761 roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
763 case ROUND_HALF_EVEN:
765 roundingMode = ROUND_DOWN;
767 roundingMode = ROUND_UP;
768 else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
769 roundingMode = ROUND_UP;
770 else // even, ROUND_HALF_DOWN
771 roundingMode = ROUND_DOWN;
776 if (roundingMode == ROUND_UP)
777 unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
779 // roundingMode == ROUND_DOWN
780 return new BigDecimal (unrounded, newScale);
784 * Performs division, if the resulting quotient requires rounding
785 * (has a nonterminating decimal expansion),
786 * an ArithmeticException is thrown.
787 * #see divide(BigDecimal, int, int)
790 public BigDecimal divide(BigDecimal divisor)
791 throws ArithmeticException, IllegalArgumentException
793 return divide(divisor, scale, ROUND_UNNECESSARY);
797 * Returns a BigDecimal whose value is the remainder in the quotient
798 * this / val. This is obtained by
799 * subtract(divideToIntegralValue(val).multiply(val)).
800 * @param val the divisor
801 * @return a BigDecimal whose value is the remainder
802 * @throws ArithmeticException if val == 0
805 public BigDecimal remainder(BigDecimal val)
807 return subtract(divideToIntegralValue(val).multiply(val));
811 * Returns a BigDecimal array, the first element of which is the integer part
812 * of this / val, and the second element of which is the remainder of
814 * @param val the divisor
815 * @return the above described BigDecimal array
816 * @throws ArithmeticException if val == 0
819 public BigDecimal[] divideAndRemainder(BigDecimal val)
821 BigDecimal[] result = new BigDecimal[2];
822 result[0] = divideToIntegralValue(val);
823 result[1] = subtract(result[0].multiply(val));
828 * Returns a BigDecimal whose value is the integer part of the quotient
829 * this / val. The preferred scale is this.scale - val.scale.
830 * @param val the divisor
831 * @return a BigDecimal whose value is the integer part of this / val.
832 * @throws ArithmeticException if val == 0
835 public BigDecimal divideToIntegralValue(BigDecimal val)
837 return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
841 * Mutates this BigDecimal into one with no fractional part, whose value is
842 * equal to the largest integer that is <= to this BigDecimal. Note that
843 * since this method is private it is okay to mutate this BigDecimal.
844 * @return the BigDecimal obtained through the floor operation on this
847 private BigDecimal floor()
851 String intValStr = intVal.toString();
852 intValStr = intValStr.substring(0, intValStr.length() - scale);
853 intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
857 public int compareTo (BigDecimal val)
859 if (scale == val.scale)
860 return intVal.compareTo (val.intVal);
862 BigInteger thisParts[] =
863 intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
864 BigInteger valParts[] =
865 val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
868 if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
871 // quotients are the same, so compare remainders
873 // Add some trailing zeros to the remainder with the smallest scale
874 if (scale < val.scale)
875 thisParts[1] = thisParts[1].multiply
876 (BigInteger.valueOf (10).pow (val.scale - scale));
877 else if (scale > val.scale)
878 valParts[1] = valParts[1].multiply
879 (BigInteger.valueOf (10).pow (scale - val.scale));
882 return thisParts[1].compareTo (valParts[1]);
885 public boolean equals (Object o)
887 return (o instanceof BigDecimal
888 && scale == ((BigDecimal) o).scale
889 && compareTo ((BigDecimal) o) == 0);
892 public int hashCode()
894 return intValue() ^ scale;
897 public BigDecimal max (BigDecimal val)
899 switch (compareTo (val))
908 public BigDecimal min (BigDecimal val)
910 switch (compareTo (val))
919 public BigDecimal movePointLeft (int n)
921 return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
924 public BigDecimal movePointRight (int n)
927 return movePointLeft (-n);
930 return new BigDecimal (intVal, scale - n);
932 return new BigDecimal (intVal.multiply
933 (BigInteger.TEN.pow (n - scale)), 0);
938 return intVal.signum ();
946 public BigInteger unscaledValue()
951 public BigDecimal abs ()
953 return new BigDecimal (intVal.abs (), scale);
956 public BigDecimal negate ()
958 return new BigDecimal (intVal.negate (), scale);
962 * Returns a BigDecimal whose value is found first by negating this via
963 * the negate() method, then by rounding according to the MathContext mc.
964 * @param mc the MathContext for rounding
965 * @return a BigDecimal whose value is approximately (-this)
966 * @throws ArithmeticException if the value is inexact but the rounding mode
967 * is RoundingMode.UNNECESSARY
970 public BigDecimal negate(MathContext mc)
972 BigDecimal result = negate();
973 if (mc.getPrecision() != 0)
974 result = result.round(mc);
979 * Returns this BigDecimal. This is included for symmetry with the
984 public BigDecimal plus()
990 * Returns a BigDecimal whose value is found by rounding <code>this</code>
991 * according to the MathContext. This is the same as round(MathContext).
992 * @param mc the MathContext for rounding
993 * @return a BigDecimal whose value is <code>this</code> before being rounded
994 * @throws ArithmeticException if the value is inexact but the rounding mode
995 * is RoundingMode.UNNECESSARY
998 public BigDecimal plus(MathContext mc)
1004 * Returns a BigDecimal which is this BigDecimal rounded according to the
1005 * MathContext rounding settings.
1006 * @param mc the MathContext that tells us how to round
1007 * @return the rounded BigDecimal
1009 public BigDecimal round(MathContext mc)
1011 int mcPrecision = mc.getPrecision();
1012 int numToChop = precision() - mcPrecision;
1013 // If mc specifies not to chop any digits or if we've already chopped
1014 // enough digits (say by using a MathContext in the constructor for this
1015 // BigDecimal) then just return this.
1016 if (mcPrecision == 0 || numToChop <= 0)
1019 // Make a new BigDecimal which is the correct power of 10 to chop off
1020 // the required number of digits and then call divide.
1021 BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
1022 BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
1023 rounded.scale -= numToChop;
1024 rounded.precision = mcPrecision;
1029 * Returns the precision of this BigDecimal (the number of digits in the
1030 * unscaled value). The precision of a zero value is 1.
1031 * @return the number of digits in the unscaled value, or 1 if the value
1034 public int precision()
1038 String s = intVal.toString();
1039 precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1045 * Returns the String representation of this BigDecimal, using scientific
1046 * notation if necessary. The following steps are taken to generate
1049 * 1. the BigInteger unscaledValue's toString method is called and if
1050 * <code>scale == 0<code> is returned.
1051 * 2. an <code>int adjExp</code> is created which is equal to the negation
1052 * of <code>scale</code> plus the number of digits in the unscaled value,
1054 * 3. if <code>scale >= 0 && adjExp >= -6</code> then we represent this
1055 * BigDecimal without scientific notation. A decimal is added if the
1056 * scale is positive and zeros are prepended as necessary.
1057 * 4. if scale is negative or adjExp is less than -6 we use scientific
1058 * notation. If the unscaled value has more than one digit, a decimal
1059 * as inserted after the first digit, the character 'E' is appended
1060 * and adjExp is appended.
1062 public String toString()
1064 // bigStr is the String representation of the unscaled value. If
1065 // scale is zero we simply return this.
1066 String bigStr = intVal.toString();
1070 boolean negative = (bigStr.charAt(0) == '-');
1071 int point = bigStr.length() - scale - (negative ? 1 : 0);
1073 StringBuilder val = new StringBuilder();
1075 if (scale >= 0 && (point - 1) >= -6)
1077 // Convert to character form without scientific notation.
1080 // Zeros need to be prepended to the StringBuilder.
1083 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1084 val.append('0').append('.');
1090 // Append the unscaled value.
1091 val.append(bigStr.substring(negative ? 1 : 0));
1095 // No zeros need to be prepended so the String is simply the
1096 // unscaled value with the decimal point inserted.
1098 val.insert(point + (negative ? 1 : 0), '.');
1103 // We must use scientific notation to represent this BigDecimal.
1105 // If there is more than one digit in the unscaled value we put a
1106 // decimal after the first digit.
1107 if (bigStr.length() > 1)
1108 val.insert( ( negative ? 2 : 1 ), '.');
1109 // And then append 'E' and the exponent = (point - 1).
1113 val.append( point - 1 );
1115 return val.toString();
1119 * Returns the String representation of this BigDecimal, using engineering
1120 * notation if necessary. This is similar to toString() but when exponents
1121 * are used the exponent is made to be a multiple of 3 such that the integer
1122 * part is between 1 and 999.
1124 * @return a String representation of this BigDecimal in engineering notation
1127 public String toEngineeringString()
1129 // bigStr is the String representation of the unscaled value. If
1130 // scale is zero we simply return this.
1131 String bigStr = intVal.toString();
1135 boolean negative = (bigStr.charAt(0) == '-');
1136 int point = bigStr.length() - scale - (negative ? 1 : 0);
1138 // This is the adjusted exponent described above.
1139 int adjExp = point - 1;
1140 StringBuilder val = new StringBuilder();
1142 if (scale >= 0 && adjExp >= -6)
1144 // Convert to character form without scientific notation.
1147 // Zeros need to be prepended to the StringBuilder.
1150 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1151 val.append('0').append('.');
1157 // Append the unscaled value.
1158 val.append(bigStr.substring(negative ? 1 : 0));
1162 // No zeros need to be prepended so the String is simply the
1163 // unscaled value with the decimal point inserted.
1165 val.insert(point + (negative ? 1 : 0), '.');
1170 // We must use scientific notation to represent this BigDecimal.
1171 // The exponent must be a multiple of 3 and the integer part
1172 // must be between 1 and 999.
1174 int zeros = adjExp % 3;
1178 // If the exponent is positive we just move the decimal to the
1179 // right and decrease the exponent until it is a multiple of 3.
1185 // If the exponent is negative then we move the dot to the right
1186 // and decrease the exponent (increase its magnitude) until
1187 // it is a multiple of 3. Note that this is not adjExp -= zeros
1188 // because the mod operator doesn't give us the distance to the
1189 // correct multiple of 3. (-5 mod 3) is -2 but the distance from
1190 // -5 to the correct multiple of 3 (-6) is 1, not 2.
1196 else if (zeros == -1)
1203 // Either we have to append zeros because, for example, 1.1E+5 should
1204 // be 110E+3, or we just have to put the decimal in the right place.
1205 if (dot > val.length())
1207 while (dot > val.length())
1210 else if (bigStr.length() > dot)
1211 val.insert(dot + (negative ? 1 : 0), '.');
1213 // And then append 'E' and the exponent (adjExp).
1219 return val.toString();
1223 * Returns a String representation of this BigDecimal without using
1224 * scientific notation. This is how toString() worked for releases 1.4
1225 * and previous. Zeros may be added to the end of the String. For
1226 * example, an unscaled value of 1234 and a scale of -3 would result in
1227 * the String 1234000, but the toString() method would return
1229 * @return a String representation of this BigDecimal
1232 public String toPlainString()
1234 // If the scale is zero we simply return the String representation of the
1236 String bigStr = intVal.toString();
1240 // Remember if we have to put a negative sign at the start.
1241 boolean negative = (bigStr.charAt(0) == '-');
1243 int point = bigStr.length() - scale - (negative ? 1 : 0);
1245 StringBuffer sb = new StringBuffer(bigStr.length() + 2
1246 + (point <= 0 ? (-point + 1) : 0));
1249 // We have to prepend zeros and a decimal point.
1252 sb.append('0').append('.');
1258 sb.append(bigStr.substring(negative ? 1 : 0));
1260 else if (point < bigStr.length())
1262 // No zeros need to be prepended or appended, just put the decimal
1263 // in the right place.
1265 sb.insert(point + (negative ? 1 : 0), '.');
1269 // We must append zeros instead of using scientific notation.
1271 for (int i = bigStr.length(); i < point; i++)
1274 return sb.toString();
1278 * Converts this BigDecimal to a BigInteger. Any fractional part will
1280 * @return a BigDecimal whose value is equal to floor[this]
1282 public BigInteger toBigInteger ()
1284 // If scale > 0 then we must divide, if scale > 0 then we must multiply,
1285 // and if scale is zero then we just return intVal;
1287 return intVal.divide (BigInteger.TEN.pow (scale));
1289 return intVal.multiply(BigInteger.TEN.pow(-scale));
1294 * Converts this BigDecimal into a BigInteger, throwing an
1295 * ArithmeticException if the conversion is not exact.
1296 * @return a BigInteger whose value is equal to the value of this BigDecimal
1299 public BigInteger toBigIntegerExact()
1303 // If we have to divide, we must check if the result is exact.
1304 BigInteger[] result =
1305 intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
1306 if (result[1].equals(BigInteger.ZERO))
1308 throw new ArithmeticException("No exact BigInteger representation");
1311 // If we're multiplying instead, then we needn't check for exactness.
1312 return intVal.multiply(BigInteger.TEN.pow(-scale));
1313 // If the scale is zero we can simply return intVal.
1317 public int intValue ()
1319 return toBigInteger ().intValue ();
1323 * Returns a BigDecimal which is numerically equal to this BigDecimal but
1324 * with no trailing zeros in the representation. For example, if this
1325 * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns
1326 * a BigDecimal with [unscaledValue, scale] = [6313, 1]. As another
1327 * example, [12400, -2] would become [124, -4].
1328 * @return a numerically equal BigDecimal with no trailing zeros
1330 public BigDecimal stripTrailingZeros()
1332 String intValStr = intVal.toString();
1333 int newScale = scale;
1334 int pointer = intValStr.length() - 1;
1335 // This loop adjusts pointer which will be used to give us the substring
1336 // of intValStr to use in our new BigDecimal, and also accordingly
1337 // adjusts the scale of our new BigDecimal.
1338 while (intValStr.charAt(pointer) == '0')
1343 // Create a new BigDecimal with the appropriate substring and then
1345 BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
1346 result.scale = newScale;
1350 public long longValue ()
1352 return toBigInteger().longValue();
1355 public float floatValue()
1357 return Float.valueOf(toString()).floatValue();
1360 public double doubleValue()
1362 return Double.valueOf(toString()).doubleValue();
1365 public BigDecimal setScale (int scale) throws ArithmeticException
1367 return setScale (scale, ROUND_UNNECESSARY);
1370 public BigDecimal setScale (int scale, int roundingMode)
1371 throws ArithmeticException, IllegalArgumentException
1373 // NOTE: The 1.5 JRE doesn't throw this, ones prior to it do and
1374 // the spec says it should. Nevertheless, if 1.6 doesn't fix this
1375 // we should consider removing it.
1376 if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
1377 return divide (ONE, scale, roundingMode);
1381 * Returns a BigDecimal whose value is the same as this BigDecimal but whose
1382 * representation has a scale of <code>newScale</code>. If the scale is
1383 * reduced then rounding may occur, according to the RoundingMode.
1385 * @param roundingMode
1386 * @return a BigDecimal whose scale is as given, whose value is
1387 * <code>this</code> with possible rounding
1388 * @throws ArithmeticException if the rounding mode is UNNECESSARY but
1389 * rounding is required
1392 public BigDecimal setScale(int newScale, RoundingMode roundingMode)
1394 return setScale(newScale, roundingMode.ordinal());
1398 * Returns a new BigDecimal constructed from the BigDecimal(String)
1399 * constructor using the Double.toString(double) method to obtain
1401 * @param val the double value used in Double.toString(double)
1402 * @return a BigDecimal representation of val
1403 * @throws NumberFormatException if val is NaN or infinite
1406 public static BigDecimal valueOf(double val)
1408 if (Double.isInfinite(val) || Double.isNaN(val))
1409 throw new NumberFormatException("argument cannot be NaN or infinite.");
1410 return new BigDecimal(Double.toString(val));
1414 * Returns a BigDecimal whose numerical value is the numerical value
1415 * of this BigDecimal multiplied by 10 to the power of <code>n</code>.
1416 * @param n the power of ten
1417 * @return the new BigDecimal
1420 public BigDecimal scaleByPowerOfTen(int n)
1422 BigDecimal result = new BigDecimal(intVal, scale - n);
1423 result.precision = precision;
1428 * Returns a BigDecimal whose value is <code>this</code> to the power of
1430 * @param n the power
1431 * @return the new BigDecimal
1434 public BigDecimal pow(int n)
1436 if (n < 0 || n > 999999999)
1437 throw new ArithmeticException("n must be between 0 and 999999999");
1438 BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
1443 * Returns a BigDecimal whose value is determined by first calling pow(n)
1444 * and then by rounding according to the MathContext mc.
1445 * @param n the power
1446 * @param mc the MathContext
1447 * @return the new BigDecimal
1448 * @throws ArithmeticException if n < 0 or n > 999999999 or if the result is
1449 * inexact but the rounding is RoundingMode.UNNECESSARY
1452 public BigDecimal pow(int n, MathContext mc)
1454 // FIXME: The specs claim to use the X3.274-1996 algorithm. We
1455 // currently do not.
1456 return pow(n).round(mc);
1460 * Returns a BigDecimal whose value is the absolute value of this BigDecimal
1461 * with rounding according to the given MathContext.
1462 * @param mc the MathContext
1463 * @return the new BigDecimal
1465 public BigDecimal abs(MathContext mc)
1467 BigDecimal result = abs();
1468 result = result.round(mc);
1473 * Returns the size of a unit in the last place of this BigDecimal. This
1474 * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()].
1475 * @return the size of a unit in the last place of <code>this</code>.
1478 public BigDecimal ulp()
1480 return new BigDecimal(BigInteger.ONE, scale);
1484 * Converts this BigDecimal to a long value.
1485 * @return the long value
1486 * @throws ArithmeticException if rounding occurs or if overflow occurs
1489 public long longValueExact()
1491 // Set scale will throw an exception if rounding occurs.
1492 BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
1493 BigInteger tempVal = temp.intVal;
1494 // Check for overflow.
1495 long result = intVal.longValue();
1496 if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
1497 || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
1498 throw new ArithmeticException("this BigDecimal is too " +
1499 "large to fit into the return type");
1501 return intVal.longValue();
1505 * Converts this BigDecimal into an int by first calling longValueExact
1506 * and then checking that the <code>long</code> returned from that
1507 * method fits into an <code>int</code>.
1508 * @return an int whose value is <code>this</code>
1509 * @throws ArithmeticException if this BigDecimal has a fractional part
1510 * or is too large to fit into an int.
1513 public int intValueExact()
1515 long temp = longValueExact();
1516 int result = (int)temp;
1518 throw new ArithmeticException ("this BigDecimal cannot fit into an int");
1523 * Converts this BigDecimal into a byte by first calling longValueExact
1524 * and then checking that the <code>long</code> returned from that
1525 * method fits into a <code>byte</code>.
1526 * @return a byte whose value is <code>this</code>
1527 * @throws ArithmeticException if this BigDecimal has a fractional part
1528 * or is too large to fit into a byte.
1531 public byte byteValueExact()
1533 long temp = longValueExact();
1534 byte result = (byte)temp;
1536 throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
1541 * Converts this BigDecimal into a short by first calling longValueExact
1542 * and then checking that the <code>long</code> returned from that
1543 * method fits into a <code>short</code>.
1544 * @return a short whose value is <code>this</code>
1545 * @throws ArithmeticException if this BigDecimal has a fractional part
1546 * or is too large to fit into a short.
1549 public short shortValueExact()
1551 long temp = longValueExact();
1552 short result = (short)temp;
1554 throw new ArithmeticException ("this BigDecimal cannot fit into a short");