001    /* java.math.BigDecimal -- Arbitrary precision decimals.
002       Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package java.math;
039    
040    import gnu.java.lang.CPStringBuilder;
041    
042    public 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    }