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 //import gnu.java.lang.CPStringBuilder;
42 public class BigDecimal //extends Number implements Comparable<BigDecimal>
44 private BigInteger intVal;
46 private int precision = 0;
47 private static final long serialVersionUID = 6108874887143696463L;
50 * The constant zero as a BigDecimal with scale zero.
53 public static final BigDecimal ZERO =
54 new BigDecimal (BigInteger.ZERO, 0);
57 * The constant one as a BigDecimal with scale zero.
60 public static final BigDecimal ONE =
61 new BigDecimal (BigInteger.ONE, 0);
64 * The constant ten as a BigDecimal with scale zero.
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;
80 * Constructs a new BigDecimal whose unscaled value is val and whose
82 * @param val the value of the new BigDecimal
85 public BigDecimal (int val)
87 this.intVal = BigInteger.valueOf(val);
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
100 /*public BigDecimal (int val, MathContext mc)
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
115 * @param val the value of the new BigDecimal
117 public BigDecimal (long val)
119 this.intVal = BigInteger.valueOf(val);
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
132 /*public BigDecimal (long val, MathContext mc)
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
155 /*public BigDecimal (BigInteger num, MathContext mc)
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
177 /*public BigDecimal (String val, MathContext mc)
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
192 * @param num the value of the new BigDecimal
194 public BigDecimal (BigInteger num)
200 * Constructs a BigDecimal whose unscaled value is num and whose
205 public BigDecimal (BigInteger num, int 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
221 /*public BigDecimal (BigInteger num, int scale, MathContext mc)
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
242 /*public BigDecimal (double num, MathContext mc)
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 Error/*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
277 exponent -= mantissaBits;
278 // Ordinary numbers have an implied leading `1' bit.
280 mantissa |= (1L << mantissaBits);
282 // Shave off factors of 10.
283 while (exponent < 0 && (mantissa & 1) == 0)
289 intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
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);
301 intVal = intVal.shiftLeft ((int) exponent);
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
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
339 * @throws ArithmeticException if the result is inexact but the rounding mode
340 * is RoundingMode.UNNECESSARY
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
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.
379 public BigDecimal(char[] in, int offset, int len)
381 // start is the index into the char array where the significand starts
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)
388 // dot is the index into the char array where the decimal point is
389 // found, or -1 if there is no decimal point
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.
399 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
401 // offset = 2, len = 8, start = 3, dot = 6, point = end = 10
405 // + 2 3 4 . 6 1 3 E - 1
406 // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
408 // offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
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] == '+')
424 else if (in[offset] == '-')
431 // Check each character looking for the decimal point and the
432 // start of the exponent.
438 // If dot != -1 then we've seen more than one decimal point.
440 throw new Error/*NumberFormatException*/("multiple `.'s in number");
443 // Break when we reach the start of the exponent.
444 else if (c == 'e' || c == 'E')
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 Error/*NumberFormatException*/("unrecognized character at " + 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);
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;
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);
472 if (val.length() == 0)
473 throw new Error/*NumberFormatException*/("no digits seen");
475 // Prepend a negative sign if necessary.
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'.
486 // Ignore a '+' sign.
487 if (in[point] == '+')
490 // Throw an exception if there were no digits found after the 'e'
493 throw new Error/*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 (Error/*NumberFormatException*/ ex)
504 throw new Error/*NumberFormatException*/("malformed exponent");
509 public BigDecimal (String num) //throws NumberFormatException
511 int len = num.length();
512 int start = 0, point = 0;
514 boolean negative = false;
515 if (num.charAt(0) == '+')
520 else if (num.charAt(0) == '-')
529 char c = num.charAt (point);
533 throw new Error/*NumberFormatException*/ ("multiple `.'s in number");
536 else if (c == 'e' || c == 'E')
538 else if (Character.digit (c, 10) < 0)
539 throw new Error/*NumberFormatException*/ ("unrecognized character: " + c);
546 val = num.substring (start, dot) + num.substring (dot + 1, point);
547 scale = point - 1 - dot;
551 val = num.substring (start, point);
554 if (val.length () == 0)
555 throw new Error/*NumberFormatException*/ ("no digits seen");
559 intVal = new BigInteger (val);
561 // Now parse exponent.
565 if (num.charAt(point) == '+')
569 throw new Error/*NumberFormatException*/ ("no exponent following e or E");
573 scale -= Integer.parseInt (num.substring (point));
575 catch (Error/*NumberFormatException*/ ex)
577 throw new Error/*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))
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
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
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
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
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
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)
714 new Error/*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);
724 // Effectively increase the scale of val to avoid an
725 // ArithmeticException for a negative power.
726 valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
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 Error/*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;
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);
760 roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
762 case ROUND_HALF_DOWN:
763 roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
765 case ROUND_HALF_EVEN:
767 roundingMode = ROUND_DOWN;
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;
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)
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
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
816 * @param val the divisor
817 * @return the above described BigDecimal array
818 * @throws ArithmeticException if val == 0
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));
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
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
849 private BigDecimal floor()
853 String intValStr = intVal.toString();
854 intValStr = intValStr.substring(0, intValStr.length() - scale);
855 intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
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));
870 if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
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));
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))
910 public BigDecimal min (BigDecimal val)
912 switch (compareTo (val))
921 public BigDecimal movePointLeft (int n)
923 return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
926 public BigDecimal movePointRight (int n)
929 return movePointLeft (-n);
932 return new BigDecimal (intVal, scale - n);
934 return new BigDecimal (intVal.multiply
935 (BigInteger.TEN.pow (n - scale)), 0);
940 return intVal.signum ();
948 public BigInteger unscaledValue()
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
972 /*public BigDecimal negate(MathContext mc)
974 BigDecimal result = negate();
975 if (mc.getPrecision() != 0)
976 result = result.round(mc);
981 * Returns this BigDecimal. This is included for symmetry with the
986 public BigDecimal plus()
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
1000 /*public BigDecimal plus(MathContext 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)
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;
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
1036 public int precision()
1040 String s = intVal.toString();
1041 precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1047 * Returns the String representation of this BigDecimal, using scientific
1048 * notation if necessary. The following steps are taken to generate
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,
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();
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.
1082 // Zeros need to be prepended to the StringBuilder.
1085 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1086 val.append('0').append('.');
1092 // Append the unscaled value.
1093 val.append(bigStr.substring(negative ? 1 : 0));
1097 // No zeros need to be prepended so the String is simply the
1098 // unscaled value with the decimal point inserted.
1100 val.insert(point + (negative ? 1 : 0), '.');
1105 // We must use scientific notation to represent this BigDecimal.
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).
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
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();
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.
1149 // Zeros need to be prepended to the StringBuilder.
1152 // Prepend a '0' and a '.' and then as many more '0's as necessary.
1153 val.append('0').append('.');
1159 // Append the unscaled value.
1160 val.append(bigStr.substring(negative ? 1 : 0));
1164 // No zeros need to be prepended so the String is simply the
1165 // unscaled value with the decimal point inserted.
1167 val.insert(point + (negative ? 1 : 0), '.');
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.
1176 int zeros = adjExp % 3;
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.
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.
1198 else if (zeros == -1)
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())
1212 else if (bigStr.length() > dot)
1213 val.insert(dot + (negative ? 1 : 0), '.');
1215 // And then append 'E' and the exponent (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
1231 * @return a String representation of this BigDecimal
1234 /*public String toPlainString()
1236 // If the scale is zero we simply return the String representation of the
1238 String bigStr = intVal.toString();
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));
1251 // We have to prepend zeros and a decimal point.
1254 sb.append('0').append('.');
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.
1267 sb.insert(point + (negative ? 1 : 0), '.');
1271 // We must append zeros instead of using scientific notation.
1273 for (int i = bigStr.length(); i < point; i++)
1276 return sb.toString();
1280 * Converts this BigDecimal to a BigInteger. Any fractional part will
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;
1289 return intVal.divide (BigInteger.TEN.pow (scale));
1291 return intVal.multiply(BigInteger.TEN.pow(-scale));
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
1301 public BigInteger toBigIntegerExact()
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))
1310 throw new Error/*ArithmeticException*/("No exact BigInteger representation");
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.
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')
1345 // Create a new BigDecimal with the appropriate substring and then
1347 BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
1348 result.scale = newScale;
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 Error/*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.
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
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
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
1408 public static BigDecimal valueOf(double val)
1410 if (Double.isInfinite(val) || Double.isNaN(val))
1411 throw new Error/*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
1422 public BigDecimal scaleByPowerOfTen(int n)
1424 BigDecimal result = new BigDecimal(intVal, scale - n);
1425 result.precision = precision;
1430 * Returns a BigDecimal whose value is <code>this</code> to the power of
1432 * @param n the power
1433 * @return the new BigDecimal
1436 public BigDecimal pow(int n)
1438 if (n < 0 || n > 999999999)
1439 throw new Error/*ArithmeticException*/("n must be between 0 and 999999999");
1440 BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
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
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);
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>.
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
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 Error/*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.
1515 public int intValueExact()
1517 long temp = longValueExact();
1518 int result = (int)temp;
1520 throw new Error/*ArithmeticException*/ ("this BigDecimal cannot fit into an int");
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.
1533 public byte byteValueExact()
1535 long temp = longValueExact();
1536 byte result = (byte)temp;
1538 throw new Error/*ArithmeticException*/ ("this BigDecimal cannot fit into a byte");
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.
1551 public short shortValueExact()
1553 long temp = longValueExact();
1554 short result = (short)temp;
1556 throw new Error/*ArithmeticException*/ ("this BigDecimal cannot fit into a short");