001/* java.math.BigDecimal -- Arbitrary precision decimals.
002   Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package java.math;
039
040import gnu.java.lang.CPStringBuilder;
041
042public class BigDecimal extends Number implements Comparable<BigDecimal>
043{
044  private BigInteger intVal;
045  private int scale;
046  private int precision = 0;
047  private static final long serialVersionUID = 6108874887143696463L;
048
049  /**
050   * The constant zero as a BigDecimal with scale zero.
051   * @since 1.5
052   */
053  public static final BigDecimal ZERO =
054    new BigDecimal (BigInteger.ZERO, 0);
055
056  /**
057   * The constant one as a BigDecimal with scale zero.
058   * @since 1.5
059   */
060  public static final BigDecimal ONE =
061    new BigDecimal (BigInteger.ONE, 0);
062
063  /**
064   * The constant ten as a BigDecimal with scale zero.
065   * @since 1.5
066   */
067  public static final BigDecimal TEN =
068    new BigDecimal (BigInteger.TEN, 0);
069
070  public static final int ROUND_UP = 0;
071  public static final int ROUND_DOWN = 1;
072  public static final int ROUND_CEILING = 2;
073  public static final int ROUND_FLOOR = 3;
074  public static final int ROUND_HALF_UP = 4;
075  public static final int ROUND_HALF_DOWN = 5;
076  public static final int ROUND_HALF_EVEN = 6;
077  public static final int ROUND_UNNECESSARY = 7;
078
079  /**
080   * Constructs a new BigDecimal whose unscaled value is val and whose
081   * scale is zero.
082   * @param val the value of the new BigDecimal
083   * @since 1.5
084   */
085  public BigDecimal (int val)
086  {
087    this.intVal = BigInteger.valueOf(val);
088    this.scale = 0;
089  }
090
091  /**
092   * Constructs a BigDecimal using the BigDecimal(int) constructor and then
093   * rounds according to the MathContext.
094   * @param val the value for the initial (unrounded) BigDecimal
095   * @param mc the MathContext specifying the rounding
096   * @throws ArithmeticException if the result is inexact but the rounding type
097   * is RoundingMode.UNNECESSARY
098   * @since 1.5
099   */
100  public BigDecimal (int val, MathContext mc)
101  {
102    this (val);
103    if (mc.getPrecision() != 0)
104      {
105        BigDecimal result = this.round(mc);
106        this.intVal = result.intVal;
107        this.scale = result.scale;
108        this.precision = result.precision;
109      }
110  }
111
112  /**
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
116   */
117  public BigDecimal (long val)
118  {
119    this.intVal = BigInteger.valueOf(val);
120    this.scale = 0;
121  }
122
123  /**
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
131   */
132  public BigDecimal (long val, MathContext mc)
133  {
134    this(val);
135    if (mc.getPrecision() != 0)
136      {
137        BigDecimal result = this.round(mc);
138        this.intVal = result.intVal;
139        this.scale = result.scale;
140        this.precision = result.precision;
141      }
142  }
143
144  /**
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
154   */
155  public BigDecimal (BigInteger num, MathContext mc)
156  {
157    this (num, 0);
158    if (mc.getPrecision() != 0)
159      {
160        BigDecimal result = this.round(mc);
161        this.intVal = result.intVal;
162        this.scale = result.scale;
163        this.precision = result.precision;
164      }
165  }
166
167  /**
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
176   */
177  public BigDecimal (String val, MathContext mc)
178  {
179    this (val);
180    if (mc.getPrecision() != 0)
181      {
182        BigDecimal result = this.round(mc);
183        this.intVal = result.intVal;
184        this.scale = result.scale;
185        this.precision = result.precision;
186      }
187  }
188
189  /**
190   * Constructs a BigDecimal whose unscaled value is num and whose
191   * scale is zero.
192   * @param num the value of the new BigDecimal
193   */
194  public BigDecimal (BigInteger num)
195  {
196    this (num, 0);
197  }
198
199  /**
200   * Constructs a BigDecimal whose unscaled value is num and whose
201   * scale is scale.
202   * @param num
203   * @param scale
204   */
205  public BigDecimal (BigInteger num, int scale)
206  {
207    this.intVal = num;
208    this.scale = scale;
209  }
210
211  /**
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
220   */
221  public BigDecimal (BigInteger num, int scale, MathContext mc)
222  {
223    this (num, scale);
224    if (mc.getPrecision() != 0)
225      {
226        BigDecimal result = this.round(mc);
227        this.intVal = result.intVal;
228        this.scale = result.scale;
229        this.precision = result.precision;
230      }
231  }
232
233  /**
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
241   */
242  public BigDecimal (double num, MathContext mc)
243  {
244    this (num);
245    if (mc.getPrecision() != 0)
246      {
247        BigDecimal result = this.round(mc);
248        this.intVal = result.intVal;
249        this.scale = result.scale;
250        this.precision = result.precision;
251      }
252  }
253
254  public BigDecimal (double num) throws NumberFormatException
255  {
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.
261
262    final int mantissaBits = 52;
263    final int exponentBits = 11;
264    final long mantMask = (1L << mantissaBits) - 1;
265    final long expMask = (1L << exponentBits) - 1;
266
267    long bits = Double.doubleToLongBits (num);
268    long mantissa = bits & mantMask;
269    long exponent = (bits >>> mantissaBits) & expMask;
270    boolean denormal = exponent == 0;
271
272    // Correct the exponent for the bias.
273    exponent -= denormal ? 1022 : 1023;
274
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);
281
282    // Shave off factors of 10.
283    while (exponent < 0 && (mantissa & 1) == 0)
284      {
285        ++exponent;
286        mantissa >>= 1;
287      }
288
289    intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
290    if (exponent < 0)
291      {
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);
298      }
299    else
300      {
301        intVal = intVal.shiftLeft ((int) exponent);
302        scale = 0;
303      }
304  }
305
306  /**
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
318   */
319  public BigDecimal(char[] in, int offset, int len, MathContext mc)
320  {
321    this(in, offset, len);
322    // If mc has precision other than zero then we must round.
323    if (mc.getPrecision() != 0)
324      {
325        BigDecimal temp = this.round(mc);
326        this.intVal = temp.intVal;
327        this.scale = temp.scale;
328        this.precision = temp.precision;
329      }
330  }
331
332  /**
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
342   */
343  public BigDecimal(char[] in, MathContext mc)
344  {
345    this(in, 0, in.length);
346    // If mc has precision other than zero then we must round.
347    if (mc.getPrecision() != 0)
348      {
349        BigDecimal temp = this.round(mc);
350        this.intVal = temp.intVal;
351        this.scale = temp.scale;
352        this.precision = temp.precision;
353      }
354  }
355
356  /**
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
363   */
364  public BigDecimal(char[] in)
365  {
366    this(in, 0, in.length);
367  }
368
369  /**
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
378   */
379  public BigDecimal(char[] in, int offset, int len)
380  {
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;
391
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.
395    //
396    //  Example 1
397    //
398    //         +  1  0  2  .  4  6  9
399    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
400    //
401    //  offset = 2, len = 8, start = 3, dot = 6, point = end = 10
402    //
403    //  Example 2
404    //
405    //         +  2  3  4  .  6  1  3  E  -  1
406    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
407    //
408    //  offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
409    //
410    //  Example 3
411    //
412    //         -  1  2  3  4  5  e  7
413    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
414    //
415    //  offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
416
417    //  Determine the sign of the number.
418    boolean negative = false;
419    if (in[offset] == '+')
420      {
421        ++start;
422        ++point;
423      }
424    else if (in[offset] == '-')
425      {
426        ++start;
427        ++point;
428        negative = true;
429      }
430
431    //  Check each character looking for the decimal point and the
432    //  start of the exponent.
433    while (point < end)
434      {
435        char c = in[point];
436        if (c == '.')
437          {
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;
442          }
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;
452      }
453
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)
458      {
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;
464      }
465    else
466      {
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;
471      }
472    if (val.length() == 0)
473      throw new NumberFormatException("no digits seen");
474
475    // Prepend a negative sign if necessary.
476    if (negative)
477      val.insert(0, '-');
478    intVal = new BigInteger(val.toString());
479
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)
484      {
485        point++;
486        // Ignore a '+' sign.
487        if (in[point] == '+')
488          point++;
489
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");
494
495        try
496          {
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));
501          }
502        catch (NumberFormatException ex)
503          {
504            throw new NumberFormatException("malformed exponent");
505          }
506      }
507  }
508
509  public BigDecimal (String num) throws NumberFormatException
510  {
511    int len = num.length();
512    int start = 0, point = 0;
513    int dot = -1;
514    boolean negative = false;
515    if (num.charAt(0) == '+')
516      {
517        ++start;
518        ++point;
519      }
520    else if (num.charAt(0) == '-')
521      {
522        ++start;
523        ++point;
524        negative = true;
525      }
526
527    while (point < len)
528      {
529        char c = num.charAt (point);
530        if (c == '.')
531          {
532            if (dot >= 0)
533              throw new NumberFormatException ("multiple `.'s in number");
534            dot = point;
535          }
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;
541      }
542
543    String val;
544    if (dot >= 0)
545      {
546        val = num.substring (start, dot) + num.substring (dot + 1, point);
547        scale = point - 1 - dot;
548      }
549    else
550      {
551        val = num.substring (start, point);
552        scale = 0;
553      }
554    if (val.length () == 0)
555      throw new NumberFormatException ("no digits seen");
556
557    if (negative)
558      val = "-" + val;
559    intVal = new BigInteger (val);
560
561    // Now parse exponent.
562    if (point < len)
563      {
564        point++;
565        if (num.charAt(point) == '+')
566          point++;
567
568        if (point >= len )
569          throw new NumberFormatException ("no exponent following e or E");
570
571        try
572          {
573        scale -= Integer.parseInt (num.substring (point));
574          }
575        catch (NumberFormatException ex)
576          {
577            throw new NumberFormatException ("malformed exponent");
578          }
579      }
580  }
581
582  public static BigDecimal valueOf (long val)
583  {
584    return valueOf (val, 0);
585  }
586
587  public static BigDecimal valueOf (long val, int scale)
588    throws NumberFormatException
589  {
590    if ((scale == 0) && ((int)val == val))
591      switch ((int) val)
592        {
593        case 0:
594          return ZERO;
595        case 1:
596          return ONE;
597        }
598
599    return new BigDecimal (BigInteger.valueOf (val), scale);
600  }
601
602  public BigDecimal add (BigDecimal val)
603  {
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));
613
614    return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
615  }
616
617  /**
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
626   */
627  public BigDecimal add (BigDecimal val, MathContext mc)
628  {
629    return add(val).round(mc);
630  }
631
632  public BigDecimal subtract (BigDecimal val)
633  {
634    return this.add(val.negate());
635  }
636
637  /**
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
646   */
647  public BigDecimal subtract (BigDecimal val, MathContext mc)
648  {
649    return subtract(val).round(mc);
650  }
651
652  public BigDecimal multiply (BigDecimal val)
653  {
654    return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
655  }
656
657  /**
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
666   */
667  public BigDecimal multiply (BigDecimal val, MathContext mc)
668  {
669    return multiply(val).round(mc);
670  }
671
672  public BigDecimal divide (BigDecimal val, int roundingMode)
673    throws ArithmeticException, IllegalArgumentException
674  {
675    return divide (val, scale, roundingMode);
676  }
677
678  /**
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
688   */
689  public BigDecimal divide(BigDecimal val,
690                           int scale, RoundingMode roundingMode)
691  {
692    return divide (val, scale, roundingMode.ordinal());
693  }
694
695  /**
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
703   */
704  public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
705  {
706    return divide (val, scale, roundingMode.ordinal());
707  }
708
709  public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
710    throws ArithmeticException, IllegalArgumentException
711  {
712    if (roundingMode < 0 || roundingMode > 7)
713      throw
714        new IllegalArgumentException("illegal rounding mode: " + roundingMode);
715
716    if (intVal.signum () == 0)  // handle special case of 0.0/0.0
717      return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
718
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)
723      {
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;
728      }
729
730    BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
731
732    BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
733
734    BigInteger unrounded = parts[0];
735    if (parts[1].signum () == 0) // no remainder, no rounding necessary
736      return new BigDecimal (unrounded, newScale);
737
738    if (roundingMode == ROUND_UNNECESSARY)
739      throw new ArithmeticException ("Rounding necessary");
740
741    int sign = intVal.signum () * valIntVal.signum ();
742
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
748      {
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);
756
757        switch(roundingMode)
758          {
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;
775          }
776      }
777
778    if (roundingMode == ROUND_UP)
779      unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
780
781    // roundingMode == ROUND_DOWN
782    return new BigDecimal (unrounded, newScale);
783  }
784
785  /**
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
791   */
792  public BigDecimal divide(BigDecimal divisor)
793    throws ArithmeticException, IllegalArgumentException
794  {
795    return divide(divisor, scale, ROUND_UNNECESSARY);
796  }
797
798  /**
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
806   */
807  public BigDecimal remainder(BigDecimal val)
808  {
809    return subtract(divideToIntegralValue(val).multiply(val));
810  }
811
812  /**
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
820   */
821  public BigDecimal[] divideAndRemainder(BigDecimal val)
822  {
823    BigDecimal[] result = new BigDecimal[2];
824    result[0] = divideToIntegralValue(val);
825    result[1] = subtract(result[0].multiply(val));
826    return result;
827  }
828
829  /**
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
836   */
837  public BigDecimal divideToIntegralValue(BigDecimal val)
838  {
839    return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
840  }
841
842  /**
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.
848   */
849  private BigDecimal floor()
850  {
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;
857  }
858
859  public int compareTo (BigDecimal val)
860  {
861    if (scale == val.scale)
862      return intVal.compareTo (val.intVal);
863
864    BigInteger thisParts[] =
865      intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
866    BigInteger valParts[] =
867      val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
868
869    int compare;
870    if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
871      return compare;
872
873    // quotients are the same, so compare remainders
874
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));
882
883    // and compare them
884    return thisParts[1].compareTo (valParts[1]);
885  }
886
887  public boolean equals (Object o)
888  {
889    return (o instanceof BigDecimal
890            && scale == ((BigDecimal) o).scale
891            && compareTo ((BigDecimal) o) == 0);
892  }
893
894  public int hashCode()
895  {
896    return intValue() ^ scale;
897  }
898
899  public BigDecimal max (BigDecimal val)
900  {
901    switch (compareTo (val))
902      {
903      case 1:
904        return this;
905      default:
906        return val;
907      }
908  }
909
910  public BigDecimal min (BigDecimal val)
911  {
912    switch (compareTo (val))
913      {
914      case -1:
915        return this;
916      default:
917        return val;
918      }
919  }
920
921  public BigDecimal movePointLeft (int n)
922  {
923    return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
924  }
925
926  public BigDecimal movePointRight (int n)
927  {
928    if (n < 0)
929      return movePointLeft (-n);
930
931    if (scale >= n)
932      return new BigDecimal (intVal, scale - n);
933
934    return new BigDecimal (intVal.multiply
935                           (BigInteger.TEN.pow (n - scale)), 0);
936  }
937
938  public int signum ()
939  {
940    return intVal.signum ();
941  }
942
943  public int scale ()
944  {
945    return scale;
946  }
947
948  public BigInteger unscaledValue()
949  {
950    return intVal;
951  }
952
953  public BigDecimal abs ()
954  {
955    return new BigDecimal (intVal.abs (), scale);
956  }
957
958  public BigDecimal negate ()
959  {
960    return new BigDecimal (intVal.negate (), scale);
961  }
962
963  /**
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
971   */
972  public BigDecimal negate(MathContext mc)
973  {
974    BigDecimal result = negate();
975    if (mc.getPrecision() != 0)
976      result = result.round(mc);
977    return result;
978  }
979
980  /**
981   * Returns this BigDecimal.  This is included for symmetry with the
982   * method negate().
983   * @return this
984   * @since 1.5
985   */
986  public BigDecimal plus()
987  {
988    return this;
989  }
990
991  /**
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
999   */
1000  public BigDecimal plus(MathContext mc)
1001  {
1002    return round(mc);
1003  }
1004
1005  /**
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
1010   */
1011  public BigDecimal round(MathContext mc)
1012  {
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;
1020
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;
1028  }
1029
1030  /**
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.
1035   */
1036  public int precision()
1037  {
1038    if (precision == 0)
1039      {
1040        String s = intVal.toString();
1041        precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1042      }
1043    return precision;
1044  }
1045
1046  /**
1047   * Returns the String representation of this BigDecimal, using scientific
1048   * notation if necessary.  The following steps are taken to generate
1049   * the result:
1050   *
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.
1063   */
1064  public String toString()
1065  {
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;
1071
1072    boolean negative = (bigStr.charAt(0) == '-');
1073    int point = bigStr.length() - scale - (negative ? 1 : 0);
1074
1075    CPStringBuilder val = new CPStringBuilder();
1076
1077    if (scale >= 0 && (point - 1) >= -6)
1078      {
1079        // Convert to character form without scientific notation.
1080        if (point <= 0)
1081          {
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)
1088              {
1089                val.append('0');
1090                point++;
1091              }
1092            // Append the unscaled value.
1093            val.append(bigStr.substring(negative ? 1 : 0));
1094          }
1095        else
1096          {
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), '.');
1101          }
1102      }
1103    else
1104      {
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 );
1116      }
1117    return val.toString();
1118  }
1119
1120  /**
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.
1125   *
1126   * @return a String representation of this BigDecimal in engineering notation
1127   * @since 1.5
1128   */
1129  public String toEngineeringString()
1130  {
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;
1136
1137    boolean negative = (bigStr.charAt(0) == '-');
1138    int point = bigStr.length() - scale - (negative ? 1 : 0);
1139
1140    // This is the adjusted exponent described above.
1141    int adjExp = point - 1;
1142    CPStringBuilder val = new CPStringBuilder();
1143
1144    if (scale >= 0 && adjExp >= -6)
1145      {
1146        // Convert to character form without scientific notation.
1147        if (point <= 0)
1148          {
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)
1155              {
1156                val.append('0');
1157                point++;
1158              }
1159            // Append the unscaled value.
1160            val.append(bigStr.substring(negative ? 1 : 0));
1161          }
1162        else
1163          {
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), '.');
1168          }
1169      }
1170    else
1171      {
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)
1179          {
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;
1184          }
1185        else
1186          {
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)
1194              {
1195                dot += 1;
1196                adjExp -= 1;
1197              }
1198            else if (zeros == -1)
1199              {
1200                dot += 2;
1201                adjExp -= 2;
1202              }
1203          }
1204
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())
1208          {
1209            while (dot > val.length())
1210              val.append('0');
1211          }
1212        else if (bigStr.length() > dot)
1213          val.insert(dot + (negative ? 1 : 0), '.');
1214
1215        // And then append 'E' and the exponent (adjExp).
1216        val.append('E');
1217        if (adjExp >= 0)
1218          val.append('+');
1219        val.append(adjExp);
1220      }
1221    return val.toString();
1222  }
1223
1224  /**
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
1233   */
1234  public String toPlainString()
1235  {
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;
1241
1242    // Remember if we have to put a negative sign at the start.
1243    boolean negative = (bigStr.charAt(0) == '-');
1244
1245    int point = bigStr.length() - scale - (negative ? 1 : 0);
1246
1247    CPStringBuilder sb = new CPStringBuilder(bigStr.length() + 2
1248                                             + (point <= 0 ? (-point + 1) : 0));
1249    if (point <= 0)
1250      {
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)
1256          {
1257            sb.append('0');
1258            point++;
1259          }
1260        sb.append(bigStr.substring(negative ? 1 : 0));
1261      }
1262    else if (point < bigStr.length())
1263      {
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), '.');
1268      }
1269    else
1270      {
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');
1275      }
1276    return sb.toString();
1277  }
1278
1279  /**
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]
1283   */
1284  public BigInteger toBigInteger ()
1285  {
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;
1293  }
1294
1295  /**
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
1300   */
1301  public BigInteger toBigIntegerExact()
1302  {
1303    if (scale > 0)
1304      {
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");
1311      }
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;
1317  }
1318
1319  public int intValue ()
1320  {
1321    return toBigInteger ().intValue ();
1322  }
1323
1324  /**
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
1331   */
1332  public BigDecimal stripTrailingZeros()
1333  {
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')
1341      {
1342        pointer --;
1343        newScale --;
1344      }
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;
1350  }
1351
1352  public long longValue ()
1353  {
1354    return toBigInteger().longValue();
1355  }
1356
1357  public float floatValue()
1358  {
1359    return Float.valueOf(toString()).floatValue();
1360  }
1361
1362  public double doubleValue()
1363  {
1364    return Double.valueOf(toString()).doubleValue();
1365  }
1366
1367  public BigDecimal setScale (int scale) throws ArithmeticException
1368  {
1369    return setScale (scale, ROUND_UNNECESSARY);
1370  }
1371
1372  public BigDecimal setScale (int scale, int roundingMode)
1373    throws ArithmeticException, IllegalArgumentException
1374  {
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);
1380  }
1381
1382  /**
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
1393   */
1394  public BigDecimal setScale(int newScale, RoundingMode roundingMode)
1395  {
1396    return setScale(newScale, roundingMode.ordinal());
1397  }
1398
1399  /**
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
1407   */
1408  public static BigDecimal valueOf(double val)
1409  {
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));
1413  }
1414
1415  /**
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
1421   */
1422  public BigDecimal scaleByPowerOfTen(int n)
1423  {
1424    BigDecimal result = new BigDecimal(intVal, scale - n);
1425    result.precision = precision;
1426    return result;
1427  }
1428
1429  /**
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
1435   */
1436  public BigDecimal pow(int n)
1437  {
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;
1442  }
1443
1444  /**
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
1453   */
1454  public BigDecimal pow(int n, MathContext mc)
1455  {
1456    // FIXME: The specs claim to use the X3.274-1996 algorithm.  We
1457    // currently do not.
1458    return pow(n).round(mc);
1459  }
1460
1461  /**
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
1466   */
1467  public BigDecimal abs(MathContext mc)
1468  {
1469    BigDecimal result = abs();
1470    result = result.round(mc);
1471    return result;
1472  }
1473
1474  /**
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
1479   */
1480  public BigDecimal ulp()
1481  {
1482    return new BigDecimal(BigInteger.ONE, scale);
1483  }
1484
1485  /**
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
1490   */
1491  public long longValueExact()
1492  {
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");
1502
1503    return intVal.longValue();
1504  }
1505
1506  /**
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
1514   */
1515  public int intValueExact()
1516  {
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;
1522  }
1523
1524  /**
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
1532   */
1533  public byte byteValueExact()
1534  {
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;
1540  }
1541
1542  /**
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
1550   */
1551  public short shortValueExact()
1552  {
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;
1558  }
1559}