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    public class BigDecimal extends Number implements Comparable<BigDecimal>
041    {
042      private BigInteger intVal;
043      private int scale;
044      private int precision = 0;
045      private static final long serialVersionUID = 6108874887143696463L;
046    
047      /**
048       * The constant zero as a BigDecimal with scale zero.
049       * @since 1.5
050       */
051      public static final BigDecimal ZERO = 
052        new BigDecimal (BigInteger.ZERO, 0);
053    
054      /**
055       * The constant one as a BigDecimal with scale zero.
056       * @since 1.5
057       */
058      public static final BigDecimal ONE = 
059        new BigDecimal (BigInteger.ONE, 0);
060    
061      /**
062       * The constant ten as a BigDecimal with scale zero.
063       * @since 1.5
064       */
065      public static final BigDecimal TEN = 
066        new BigDecimal (BigInteger.TEN, 0);
067    
068      public static final int ROUND_UP = 0;
069      public static final int ROUND_DOWN = 1;
070      public static final int ROUND_CEILING = 2;
071      public static final int ROUND_FLOOR = 3;
072      public static final int ROUND_HALF_UP = 4;
073      public static final int ROUND_HALF_DOWN = 5;
074      public static final int ROUND_HALF_EVEN = 6;
075      public static final int ROUND_UNNECESSARY = 7;
076    
077      /**
078       * Constructs a new BigDecimal whose unscaled value is val and whose
079       * scale is zero.
080       * @param val the value of the new BigDecimal
081       * @since 1.5
082       */
083      public BigDecimal (int val)
084      {
085        this.intVal = BigInteger.valueOf(val);
086        this.scale = 0;
087      }
088      
089      /**
090       * Constructs a BigDecimal using the BigDecimal(int) constructor and then
091       * rounds according to the MathContext.
092       * @param val the value for the initial (unrounded) BigDecimal
093       * @param mc the MathContext specifying the rounding
094       * @throws ArithmeticException if the result is inexact but the rounding type
095       * is RoundingMode.UNNECESSARY
096       * @since 1.5
097       */
098      public BigDecimal (int val, MathContext mc)
099      {
100        this (val);
101        if (mc.getPrecision() != 0)
102          {
103            BigDecimal result = this.round(mc);
104            this.intVal = result.intVal;
105            this.scale = result.scale;
106            this.precision = result.precision;
107          }    
108      }
109      
110      /**
111       * Constructs a new BigDecimal whose unscaled value is val and whose
112       * scale is zero.
113       * @param val the value of the new BigDecimal
114       */
115      public BigDecimal (long val)
116      {
117        this.intVal = BigInteger.valueOf(val);
118        this.scale = 0;
119      }
120      
121      /**
122       * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
123       * and then rounds according to the MathContext.
124       * @param val the long from which we create the initial BigDecimal
125       * @param mc the MathContext that specifies the rounding behaviour
126       * @throws ArithmeticException if the result is inexact but the rounding type
127       * is RoundingMode.UNNECESSARY
128       * @since 1.5
129       */
130      public BigDecimal (long val, MathContext mc)
131      {
132        this(val);
133        if (mc.getPrecision() != 0)
134          {
135            BigDecimal result = this.round(mc);
136            this.intVal = result.intVal;
137            this.scale = result.scale;
138            this.precision = result.precision;
139          }    
140      }
141      
142      /**
143       * Constructs a BigDecimal whose value is given by num rounded according to 
144       * mc.  Since num is already a BigInteger, the rounding refers only to the 
145       * precision setting in mc, if mc.getPrecision() returns an int lower than
146       * the number of digits in num, then rounding is necessary.
147       * @param num the unscaledValue, before rounding
148       * @param mc the MathContext that specifies the precision
149       * @throws ArithmeticException if the result is inexact but the rounding type
150       * is RoundingMode.UNNECESSARY
151       * * @since 1.5
152       */
153      public BigDecimal (BigInteger num, MathContext mc)
154      {
155        this (num, 0);
156        if (mc.getPrecision() != 0)
157          {
158            BigDecimal result = this.round(mc);
159            this.intVal = result.intVal;
160            this.scale = result.scale;
161            this.precision = result.precision;
162          }
163      }
164      
165      /**
166       * Constructs a BigDecimal from the String val according to the same
167       * rules as the BigDecimal(String) constructor and then rounds 
168       * according to the MathContext mc.
169       * @param val the String from which we construct the initial BigDecimal
170       * @param mc the MathContext that specifies the rounding
171       * @throws ArithmeticException if the result is inexact but the rounding type
172       * is RoundingMode.UNNECESSARY   
173       * @since 1.5
174       */
175      public BigDecimal (String val, MathContext mc)
176      {
177        this (val);
178        if (mc.getPrecision() != 0)
179          {
180            BigDecimal result = this.round(mc);
181            this.intVal = result.intVal;
182            this.scale = result.scale;
183            this.precision = result.precision;
184          }
185      }
186      
187      /**
188       * Constructs a BigDecimal whose unscaled value is num and whose
189       * scale is zero.
190       * @param num the value of the new BigDecimal
191       */
192      public BigDecimal (BigInteger num) 
193      {
194        this (num, 0);
195      }
196    
197      /**
198       * Constructs a BigDecimal whose unscaled value is num and whose
199       * scale is scale.
200       * @param num
201       * @param scale
202       */
203      public BigDecimal (BigInteger num, int scale)
204      {
205        this.intVal = num;
206        this.scale = scale;
207      }
208      
209      /**
210       * Constructs a BigDecimal using the BigDecimal(BigInteger, int) 
211       * constructor and then rounds according to the MathContext.
212       * @param num the unscaled value of the unrounded BigDecimal
213       * @param scale the scale of the unrounded BigDecimal
214       * @param mc the MathContext specifying the rounding
215       * @throws ArithmeticException if the result is inexact but the rounding type
216       * is RoundingMode.UNNECESSARY
217       * @since 1.5
218       */
219      public BigDecimal (BigInteger num, int scale, MathContext mc)
220      {
221        this (num, scale);
222        if (mc.getPrecision() != 0)
223          {
224            BigDecimal result = this.round(mc);
225            this.intVal = result.intVal;
226            this.scale = result.scale;
227            this.precision = result.precision;
228          }
229      }
230    
231      /**
232       * Constructs a BigDecimal in the same way as BigDecimal(double) and then
233       * rounds according to the MathContext.
234       * @param num the double from which the initial BigDecimal is created
235       * @param mc the MathContext that specifies the rounding behaviour
236       * @throws ArithmeticException if the result is inexact but the rounding type
237       * is RoundingMode.UNNECESSARY 
238       * @since 1.5
239       */
240      public BigDecimal (double num, MathContext mc)
241      {
242        this (num);
243        if (mc.getPrecision() != 0)
244          {
245            BigDecimal result = this.round(mc);
246            this.intVal = result.intVal;
247            this.scale = result.scale;
248            this.precision = result.precision;
249          }
250      }
251      
252      public BigDecimal (double num) throws NumberFormatException 
253      {
254        if (Double.isInfinite (num) || Double.isNaN (num))
255          throw new NumberFormatException ("invalid argument: " + num);
256        // Note we can't convert NUM to a String and then use the
257        // String-based constructor.  The BigDecimal documentation makes
258        // it clear that the two constructors work differently.
259    
260        final int mantissaBits = 52;
261        final int exponentBits = 11;
262        final long mantMask = (1L << mantissaBits) - 1;
263        final long expMask = (1L << exponentBits) - 1;
264    
265        long bits = Double.doubleToLongBits (num);
266        long mantissa = bits & mantMask;
267        long exponent = (bits >>> mantissaBits) & expMask;
268        boolean denormal = exponent == 0;
269    
270        // Correct the exponent for the bias.
271        exponent -= denormal ? 1022 : 1023;
272    
273        // Now correct the exponent to account for the bits to the right
274        // of the decimal.
275        exponent -= mantissaBits;
276        // Ordinary numbers have an implied leading `1' bit.
277        if (! denormal)
278          mantissa |= (1L << mantissaBits);
279    
280        // Shave off factors of 10.
281        while (exponent < 0 && (mantissa & 1) == 0)
282          {
283            ++exponent;
284            mantissa >>= 1;
285          }
286    
287        intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
288        if (exponent < 0)
289          {
290            // We have MANTISSA * 2 ^ (EXPONENT).
291            // Since (1/2)^N == 5^N * 10^-N we can easily convert this
292            // into a power of 10.
293            scale = (int) (- exponent);
294            BigInteger mult = BigInteger.valueOf (5).pow (scale);
295            intVal = intVal.multiply (mult);
296          }
297        else
298          {
299            intVal = intVal.shiftLeft ((int) exponent);
300            scale = 0;
301          }
302      }
303    
304      /**
305       * Constructs a BigDecimal from the char subarray and rounding 
306       * according to the MathContext.
307       * @param in the char array
308       * @param offset the start of the subarray
309       * @param len the length of the subarray
310       * @param mc the MathContext for rounding
311       * @throws NumberFormatException if the char subarray is not a valid 
312       * BigDecimal representation
313       * @throws ArithmeticException if the result is inexact but the rounding 
314       * mode is RoundingMode.UNNECESSARY
315       * @since 1.5
316       */
317      public BigDecimal(char[] in, int offset, int len, MathContext mc)
318      {
319        this(in, offset, len);
320        // If mc has precision other than zero then we must round.
321        if (mc.getPrecision() != 0)
322          {
323            BigDecimal temp = this.round(mc);
324            this.intVal = temp.intVal;
325            this.scale = temp.scale;
326            this.precision = temp.precision;
327          }
328      }
329      
330      /**
331       * Constructs a BigDecimal from the char array and rounding according
332       * to the MathContext. 
333       * @param in the char array
334       * @param mc the MathContext
335       * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
336       * representation
337       * @throws ArithmeticException if the result is inexact but the rounding mode
338       * is RoundingMode.UNNECESSARY
339       * @since 1.5
340       */
341      public BigDecimal(char[] in, MathContext mc)
342      {
343        this(in, 0, in.length);
344        // If mc has precision other than zero then we must round.
345        if (mc.getPrecision() != 0)
346          {
347            BigDecimal temp = this.round(mc);
348            this.intVal = temp.intVal;
349            this.scale = temp.scale;
350            this.precision = temp.precision;
351          } 
352      }
353      
354      /**
355       * Constructs a BigDecimal from the given char array, accepting the same
356       * sequence of characters as the BigDecimal(String) constructor.
357       * @param in the char array
358       * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
359       * representation
360       * @since 1.5
361       */
362      public BigDecimal(char[] in)
363      {
364        this(in, 0, in.length);
365      }
366      
367      /**
368       * Constructs a BigDecimal from a char subarray, accepting the same sequence
369       * of characters as the BigDecimal(String) constructor.  
370       * @param in the char array
371       * @param offset the start of the subarray
372       * @param len the length of the subarray
373       * @throws NumberFormatException if <code>in</code> is not a valid
374       * BigDecimal representation.
375       * @since 1.5
376       */
377      public BigDecimal(char[] in, int offset, int len)
378      {
379        //  start is the index into the char array where the significand starts
380        int start = offset;
381        //  end is one greater than the index of the last character used
382        int end = offset + len;
383        //  point is the index into the char array where the exponent starts
384        //  (or, if there is no exponent, this is equal to end)
385        int point = offset;
386        //  dot is the index into the char array where the decimal point is 
387        //  found, or -1 if there is no decimal point
388        int dot = -1;
389        
390        //  The following examples show what these variables mean.  Note that
391        //  point and dot don't yet have the correct values, they will be 
392        //  properly assigned in a loop later on in this method.
393        //
394        //  Example 1
395        //
396        //         +  1  0  2  .  4  6  9
397        //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
398        //
399        //  offset = 2, len = 8, start = 3, dot = 6, point = end = 10
400        //
401        //  Example 2
402        //
403        //         +  2  3  4  .  6  1  3  E  -  1
404        //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
405        //
406        //  offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
407        //
408        //  Example 3
409        //
410        //         -  1  2  3  4  5  e  7  
411        //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
412        //
413        //  offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10 
414        
415        //  Determine the sign of the number.
416        boolean negative = false;
417        if (in[offset] == '+')
418          {
419            ++start;
420            ++point;
421          }
422        else if (in[offset] == '-')
423          {
424            ++start;
425            ++point;
426            negative = true;
427          }
428    
429        //  Check each character looking for the decimal point and the 
430        //  start of the exponent.
431        while (point < end)
432          {
433            char c = in[point];
434            if (c == '.')
435              {
436                // If dot != -1 then we've seen more than one decimal point.
437                if (dot != -1)
438                  throw new NumberFormatException("multiple `.'s in number");
439                dot = point;
440              }
441            // Break when we reach the start of the exponent.
442            else if (c == 'e' || c == 'E')
443              break;
444            // Throw an exception if the character was not a decimal or an 
445            // exponent and is not a digit.
446            else if (!Character.isDigit(c))
447              throw new NumberFormatException("unrecognized character at " + point
448                                              + ": " + c);
449            ++point;
450          }
451    
452        // val is a StringBuilder from which we'll create a BigInteger
453        // which will be the unscaled value for this BigDecimal
454        StringBuilder val = new StringBuilder(point - start - 1);
455        if (dot != -1)
456          {
457            // If there was a decimal we must combine the two parts that 
458            // contain only digits and we must set the scale properly.
459            val.append(in, start, dot - start);
460            val.append(in, dot + 1, point - dot - 1);
461            scale = point - 1 - dot;
462          }
463        else
464          {
465            // If there was no decimal then the unscaled value is just the number
466            // formed from all the digits and the scale is zero.
467            val.append(in, start, point - start);
468            scale = 0;
469          }
470        if (val.length() == 0)
471          throw new NumberFormatException("no digits seen");
472    
473        // Prepend a negative sign if necessary.
474        if (negative)
475          val.insert(0, '-');
476        intVal = new BigInteger(val.toString());
477    
478        // Now parse exponent.
479        // If point < end that means we broke out of the previous loop when we
480        // saw an 'e' or an 'E'.
481        if (point < end)
482          {
483            point++;
484            // Ignore a '+' sign.
485            if (in[point] == '+')
486              point++;
487    
488            // Throw an exception if there were no digits found after the 'e'
489            // or 'E'.
490            if (point >= end)
491              throw new NumberFormatException("no exponent following e or E");
492    
493            try
494              {
495                // Adjust the scale according to the exponent.  
496                // Remember that the value of a BigDecimal is
497                // unscaledValue x Math.pow(10, -scale)
498                scale -= Integer.parseInt(new String(in, point, end - point));
499              }
500            catch (NumberFormatException ex)
501              {
502                throw new NumberFormatException("malformed exponent");
503              }
504          }
505      }
506      
507      public BigDecimal (String num) throws NumberFormatException 
508      {
509        int len = num.length();
510        int start = 0, point = 0;
511        int dot = -1;
512        boolean negative = false;
513        if (num.charAt(0) == '+')
514          {
515            ++start;
516            ++point;
517          }
518        else if (num.charAt(0) == '-')
519          {
520            ++start;
521            ++point;
522            negative = true;
523          }
524    
525        while (point < len)
526          {
527            char c = num.charAt (point);
528            if (c == '.')
529              {
530                if (dot >= 0)
531                  throw new NumberFormatException ("multiple `.'s in number");
532                dot = point;
533              }
534            else if (c == 'e' || c == 'E')
535              break;
536            else if (Character.digit (c, 10) < 0)
537              throw new NumberFormatException ("unrecognized character: " + c);
538            ++point;
539          }
540    
541        String val;
542        if (dot >= 0)
543          {
544            val = num.substring (start, dot) + num.substring (dot + 1, point);
545            scale = point - 1 - dot;
546          }
547        else
548          {
549            val = num.substring (start, point);
550            scale = 0;
551          }
552        if (val.length () == 0)
553          throw new NumberFormatException ("no digits seen");
554    
555        if (negative)
556          val = "-" + val;
557        intVal = new BigInteger (val);
558    
559        // Now parse exponent.
560        if (point < len)
561          {
562            point++;
563            if (num.charAt(point) == '+')
564              point++;
565    
566            if (point >= len )
567              throw new NumberFormatException ("no exponent following e or E");
568            
569            try 
570              {         
571            scale -= Integer.parseInt (num.substring (point));
572              }
573            catch (NumberFormatException ex) 
574              {
575                throw new NumberFormatException ("malformed exponent");
576              }
577          }
578      }
579    
580      public static BigDecimal valueOf (long val) 
581      {
582        return valueOf (val, 0);
583      }
584    
585      public static BigDecimal valueOf (long val, int scale) 
586        throws NumberFormatException 
587      {
588        if ((scale == 0) && ((int)val == val))
589          switch ((int) val)
590            {
591            case 0:
592              return ZERO;
593            case 1:
594              return ONE;
595            }
596    
597        return new BigDecimal (BigInteger.valueOf (val), scale);
598      }
599    
600      public BigDecimal add (BigDecimal val) 
601      {
602        // For addition, need to line up decimals.  Note that the movePointRight
603        // method cannot be used for this as it might return a BigDecimal with
604        // scale == 0 instead of the scale we need.
605        BigInteger op1 = intVal;
606        BigInteger op2 = val.intVal;
607        if (scale < val.scale)
608          op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
609        else if (scale > val.scale)
610          op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
611    
612        return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
613      }
614      
615      /**
616       * Returns a BigDecimal whose value is found first by calling the 
617       * method add(val) and then by rounding according to the MathContext mc.
618       * @param val the augend
619       * @param mc the MathContext for rounding
620       * @throws ArithmeticException if the value is inexact but the rounding is
621       * RoundingMode.UNNECESSARY
622       * @return <code>this</code> + <code>val</code>, rounded if need be
623       * @since 1.5
624       */
625      public BigDecimal add (BigDecimal val, MathContext mc)
626      {
627        return add(val).round(mc);
628      }
629    
630      public BigDecimal subtract (BigDecimal val) 
631      {
632        return this.add(val.negate());
633      }
634    
635      /**
636       * Returns a BigDecimal whose value is found first by calling the 
637       * method subtract(val) and then by rounding according to the MathContext mc.
638       * @param val the subtrahend
639       * @param mc the MathContext for rounding
640       * @throws ArithmeticException if the value is inexact but the rounding is
641       * RoundingMode.UNNECESSARY
642       * @return <code>this</code> - <code>val</code>, rounded if need be
643       * @since 1.5
644       */
645      public BigDecimal subtract (BigDecimal val, MathContext mc)
646      {
647        return subtract(val).round(mc);
648      }
649    
650      public BigDecimal multiply (BigDecimal val) 
651      {
652        return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
653      }
654      
655      /**
656       * Returns a BigDecimal whose value is (this x val) before it is rounded
657       * according to the MathContext mc. 
658       * @param val the multiplicand
659       * @param mc the MathContext for rounding
660       * @return a new BigDecimal with value approximately (this x val)
661       * @throws ArithmeticException if the value is inexact but the rounding mode
662       * is RoundingMode.UNNECESSARY
663       * @since 1.5
664       */
665      public BigDecimal multiply (BigDecimal val, MathContext mc)
666      {
667        return multiply(val).round(mc);
668      }
669    
670      public BigDecimal divide (BigDecimal val, int roundingMode) 
671        throws ArithmeticException, IllegalArgumentException 
672      {
673        return divide (val, scale, roundingMode);
674      }
675      
676      /**
677       * Returns a BigDecimal whose value is (this / val), with the specified scale
678       * and rounding according to the RoundingMode 
679       * @param val the divisor
680       * @param scale the scale of the BigDecimal returned
681       * @param roundingMode the rounding mode to use
682       * @return a BigDecimal whose value is approximately (this / val)
683       * @throws ArithmeticException if divisor is zero or the rounding mode is
684       * UNNECESSARY but the specified scale cannot represent the value exactly
685       * @since 1.5
686       */
687      public BigDecimal divide(BigDecimal val, 
688                               int scale, RoundingMode roundingMode)
689      {
690        return divide (val, scale, roundingMode.ordinal());
691      }
692    
693      /**
694       * Returns a BigDecimal whose value is (this / val) rounded according to the
695       * RoundingMode
696       * @param val the divisor
697       * @param roundingMode the rounding mode to use
698       * @return a BigDecimal whose value is approximately (this / val)
699       * @throws ArithmeticException if divisor is zero or the rounding mode is
700       * UNNECESSARY but the specified scale cannot represent the value exactly
701       */
702      public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
703      {
704        return divide (val, scale, roundingMode.ordinal());
705      }
706      
707      public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
708        throws ArithmeticException, IllegalArgumentException 
709      {
710        if (roundingMode < 0 || roundingMode > 7)
711          throw 
712            new IllegalArgumentException("illegal rounding mode: " + roundingMode);
713    
714        if (intVal.signum () == 0)  // handle special case of 0.0/0.0
715          return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
716        
717        // Ensure that pow gets a non-negative value.
718        BigInteger valIntVal = val.intVal;
719        int power = newScale - (scale - val.scale);
720        if (power < 0)
721          {
722            // Effectively increase the scale of val to avoid an
723            // ArithmeticException for a negative power.
724            valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
725            power = 0;
726          }
727    
728        BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
729        
730        BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
731    
732        BigInteger unrounded = parts[0];
733        if (parts[1].signum () == 0) // no remainder, no rounding necessary
734          return new BigDecimal (unrounded, newScale);
735    
736        if (roundingMode == ROUND_UNNECESSARY)
737          throw new ArithmeticException ("Rounding necessary");
738    
739        int sign = intVal.signum () * valIntVal.signum ();
740    
741        if (roundingMode == ROUND_CEILING)
742          roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
743        else if (roundingMode == ROUND_FLOOR)
744          roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
745        else
746          {
747            // half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
748            // 1 if >. This implies that the remainder to round is less than,
749            // equal to, or greater than half way to the next digit.
750            BigInteger posRemainder
751              = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
752            valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
753            int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
754    
755            switch(roundingMode)
756              {
757              case ROUND_HALF_UP:
758                roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
759                break;
760              case ROUND_HALF_DOWN:
761                roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
762                break;
763              case ROUND_HALF_EVEN:
764                if (half < 0)
765                  roundingMode = ROUND_DOWN;
766                else if (half > 0)
767                  roundingMode = ROUND_UP;
768                else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
769                  roundingMode = ROUND_UP;
770                else                           // even, ROUND_HALF_DOWN
771                  roundingMode = ROUND_DOWN;
772                break;
773              }
774          }
775    
776        if (roundingMode == ROUND_UP)
777          unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
778    
779        // roundingMode == ROUND_DOWN
780        return new BigDecimal (unrounded, newScale);
781      }
782      
783      /**
784       * Performs division, if the resulting quotient requires rounding
785       * (has a nonterminating decimal expansion), 
786       * an ArithmeticException is thrown. 
787       * #see divide(BigDecimal, int, int)
788       * @since 1.5
789       */
790      public BigDecimal divide(BigDecimal divisor)
791        throws ArithmeticException, IllegalArgumentException 
792      {
793        return divide(divisor, scale, ROUND_UNNECESSARY);
794      }
795    
796      /**
797       * Returns a BigDecimal whose value is the remainder in the quotient
798       * this / val.  This is obtained by 
799       * subtract(divideToIntegralValue(val).multiply(val)).  
800       * @param val the divisor
801       * @return a BigDecimal whose value is the remainder
802       * @throws ArithmeticException if val == 0
803       * @since 1.5
804       */
805      public BigDecimal remainder(BigDecimal val)
806      {
807        return subtract(divideToIntegralValue(val).multiply(val));
808      }
809    
810      /**
811       * Returns a BigDecimal array, the first element of which is the integer part
812       * of this / val, and the second element of which is the remainder of 
813       * that quotient.
814       * @param val the divisor
815       * @return the above described BigDecimal array
816       * @throws ArithmeticException if val == 0
817       * @since 1.5
818       */
819      public BigDecimal[] divideAndRemainder(BigDecimal val)
820      {
821        BigDecimal[] result = new BigDecimal[2];
822        result[0] = divideToIntegralValue(val);
823        result[1] = subtract(result[0].multiply(val));
824        return result;
825      }
826      
827      /**
828       * Returns a BigDecimal whose value is the integer part of the quotient 
829       * this / val.  The preferred scale is this.scale - val.scale.
830       * @param val the divisor
831       * @return a BigDecimal whose value is the integer part of this / val.
832       * @throws ArithmeticException if val == 0
833       * @since 1.5
834       */
835      public BigDecimal divideToIntegralValue(BigDecimal val)
836      {
837        return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
838      }
839      
840      /**
841       * Mutates this BigDecimal into one with no fractional part, whose value is 
842       * equal to the largest integer that is <= to this BigDecimal.  Note that
843       * since this method is private it is okay to mutate this BigDecimal.
844       * @return the BigDecimal obtained through the floor operation on this 
845       * BigDecimal.
846       */
847      private BigDecimal floor()
848      {
849        if (scale <= 0)
850          return this;
851        String intValStr = intVal.toString();
852        intValStr = intValStr.substring(0, intValStr.length() - scale);
853        intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
854        return this;
855      }
856        
857      public int compareTo (BigDecimal val) 
858      {
859        if (scale == val.scale)
860          return intVal.compareTo (val.intVal);
861    
862        BigInteger thisParts[] = 
863          intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
864        BigInteger valParts[] =
865          val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
866        
867        int compare;
868        if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
869          return compare;
870    
871        // quotients are the same, so compare remainders
872    
873        // Add some trailing zeros to the remainder with the smallest scale
874        if (scale < val.scale)
875          thisParts[1] = thisParts[1].multiply
876                            (BigInteger.valueOf (10).pow (val.scale - scale));
877        else if (scale > val.scale)
878          valParts[1] = valParts[1].multiply
879                            (BigInteger.valueOf (10).pow (scale - val.scale));
880    
881        // and compare them
882        return thisParts[1].compareTo (valParts[1]);
883      }
884    
885      public boolean equals (Object o) 
886      {
887        return (o instanceof BigDecimal 
888                && scale == ((BigDecimal) o).scale
889                && compareTo ((BigDecimal) o) == 0);
890      }
891    
892      public int hashCode() 
893      {
894        return intValue() ^ scale;
895      }
896    
897      public BigDecimal max (BigDecimal val)
898      {
899        switch (compareTo (val)) 
900          {
901          case 1:
902            return this;
903          default:
904            return val;
905          }
906      }
907    
908      public BigDecimal min (BigDecimal val) 
909      {
910        switch (compareTo (val)) 
911          {
912          case -1:
913            return this;
914          default:
915            return val;
916          }
917      }
918    
919      public BigDecimal movePointLeft (int n)
920      {
921        return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
922      }
923    
924      public BigDecimal movePointRight (int n)
925      {
926        if (n < 0)
927          return movePointLeft (-n);
928    
929        if (scale >= n)
930          return new BigDecimal (intVal, scale - n);
931    
932        return new BigDecimal (intVal.multiply 
933                               (BigInteger.TEN.pow (n - scale)), 0);
934      }
935    
936      public int signum () 
937      {
938        return intVal.signum ();
939      }
940    
941      public int scale () 
942      {
943        return scale;
944      }
945      
946      public BigInteger unscaledValue()
947      {
948        return intVal;
949      }
950    
951      public BigDecimal abs () 
952      {
953        return new BigDecimal (intVal.abs (), scale);
954      }
955    
956      public BigDecimal negate () 
957      {
958        return new BigDecimal (intVal.negate (), scale);
959      }
960      
961      /**
962       * Returns a BigDecimal whose value is found first by negating this via
963       * the negate() method, then by rounding according to the MathContext mc.
964       * @param mc the MathContext for rounding
965       * @return a BigDecimal whose value is approximately (-this)
966       * @throws ArithmeticException if the value is inexact but the rounding mode
967       * is RoundingMode.UNNECESSARY
968       * @since 1.5
969       */
970      public BigDecimal negate(MathContext mc)
971      {
972        BigDecimal result = negate();
973        if (mc.getPrecision() != 0)
974          result = result.round(mc);
975        return result;
976      }
977      
978      /**
979       * Returns this BigDecimal.  This is included for symmetry with the 
980       * method negate().
981       * @return this
982       * @since 1.5
983       */
984      public BigDecimal plus()
985      {
986        return this;
987      }
988      
989      /**
990       * Returns a BigDecimal whose value is found by rounding <code>this</code> 
991       * according to the MathContext.  This is the same as round(MathContext).
992       * @param mc the MathContext for rounding
993       * @return a BigDecimal whose value is <code>this</code> before being rounded
994       * @throws ArithmeticException if the value is inexact but the rounding mode
995       * is RoundingMode.UNNECESSARY
996       * @since 1.5
997       */
998      public BigDecimal plus(MathContext mc)
999      {
1000        return round(mc);
1001      }
1002      
1003      /**
1004       * Returns a BigDecimal which is this BigDecimal rounded according to the
1005       * MathContext rounding settings.
1006       * @param mc the MathContext that tells us how to round
1007       * @return the rounded BigDecimal
1008       */
1009      public BigDecimal round(MathContext mc)
1010      {
1011        int mcPrecision = mc.getPrecision();
1012        int numToChop = precision() - mcPrecision;
1013        // If mc specifies not to chop any digits or if we've already chopped 
1014        // enough digits (say by using a MathContext in the constructor for this
1015        // BigDecimal) then just return this.
1016        if (mcPrecision == 0 || numToChop <= 0)
1017          return this;
1018        
1019        // Make a new BigDecimal which is the correct power of 10 to chop off
1020        // the required number of digits and then call divide.
1021        BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
1022        BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
1023        rounded.scale -= numToChop;
1024        rounded.precision = mcPrecision;
1025        return rounded;
1026      }
1027      
1028      /**
1029       * Returns the precision of this BigDecimal (the number of digits in the
1030       * unscaled value).  The precision of a zero value is 1.
1031       * @return the number of digits in the unscaled value, or 1 if the value 
1032       * is zero.
1033       */
1034      public int precision()
1035      {
1036        if (precision == 0)
1037          {
1038            String s = intVal.toString();
1039            precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1040          }
1041        return precision;
1042      }
1043      
1044      /**
1045       * Returns the String representation of this BigDecimal, using scientific
1046       * notation if necessary.  The following steps are taken to generate
1047       * the result:
1048       * 
1049       * 1. the BigInteger unscaledValue's toString method is called and if
1050       * <code>scale == 0<code> is returned.
1051       * 2. an <code>int adjExp</code> is created which is equal to the negation
1052       * of <code>scale</code> plus the number of digits in the unscaled value, 
1053       * minus one.
1054       * 3. if <code>scale >= 0 && adjExp >= -6</code> then we represent this 
1055       * BigDecimal without scientific notation.  A decimal is added if the 
1056       * scale is positive and zeros are prepended as necessary.
1057       * 4. if scale is negative or adjExp is less than -6 we use scientific
1058       * notation.  If the unscaled value has more than one digit, a decimal 
1059       * as inserted after the first digit, the character 'E' is appended
1060       * and adjExp is appended.
1061       */
1062      public String toString()
1063      {
1064        // bigStr is the String representation of the unscaled value.  If
1065        // scale is zero we simply return this.
1066        String bigStr = intVal.toString();
1067        if (scale == 0)
1068          return bigStr;
1069    
1070        boolean negative = (bigStr.charAt(0) == '-');
1071        int point = bigStr.length() - scale - (negative ? 1 : 0);
1072    
1073        StringBuilder val = new StringBuilder();
1074    
1075        if (scale >= 0 && (point - 1) >= -6)
1076          {
1077            // Convert to character form without scientific notation.
1078            if (point <= 0)
1079              {
1080                // Zeros need to be prepended to the StringBuilder.
1081                if (negative)
1082                  val.append('-');
1083                // Prepend a '0' and a '.' and then as many more '0's as necessary.
1084                val.append('0').append('.');
1085                while (point < 0)
1086                  {
1087                    val.append('0');
1088                    point++;
1089                  }
1090                // Append the unscaled value.
1091                val.append(bigStr.substring(negative ? 1 : 0));
1092              }
1093            else
1094              {
1095                // No zeros need to be prepended so the String is simply the 
1096                // unscaled value with the decimal point inserted.
1097                val.append(bigStr);
1098                val.insert(point + (negative ? 1 : 0), '.');
1099              }
1100          }
1101        else
1102          {
1103            // We must use scientific notation to represent this BigDecimal.
1104            val.append(bigStr);
1105            // If there is more than one digit in the unscaled value we put a 
1106            // decimal after the first digit.
1107            if (bigStr.length() > 1)
1108              val.insert( ( negative ? 2 : 1 ), '.');
1109            // And then append 'E' and the exponent = (point - 1).
1110            val.append('E');
1111            if (point - 1 >= 0)
1112              val.append('+');
1113            val.append( point - 1 );
1114          }
1115        return val.toString();
1116      }
1117    
1118      /**
1119       * Returns the String representation of this BigDecimal, using engineering
1120       * notation if necessary.  This is similar to toString() but when exponents 
1121       * are used the exponent is made to be a multiple of 3 such that the integer
1122       * part is between 1 and 999.
1123       * 
1124       * @return a String representation of this BigDecimal in engineering notation
1125       * @since 1.5
1126       */
1127      public String toEngineeringString()
1128      {
1129        // bigStr is the String representation of the unscaled value.  If
1130        // scale is zero we simply return this.
1131        String bigStr = intVal.toString();
1132        if (scale == 0)
1133          return bigStr;
1134    
1135        boolean negative = (bigStr.charAt(0) == '-');
1136        int point = bigStr.length() - scale - (negative ? 1 : 0);
1137    
1138        // This is the adjusted exponent described above.
1139        int adjExp = point - 1;
1140        StringBuilder val = new StringBuilder();
1141    
1142        if (scale >= 0 && adjExp >= -6)
1143          {
1144            // Convert to character form without scientific notation.
1145            if (point <= 0)
1146              {
1147                // Zeros need to be prepended to the StringBuilder.
1148                if (negative)
1149                  val.append('-');
1150                // Prepend a '0' and a '.' and then as many more '0's as necessary.
1151                val.append('0').append('.');
1152                while (point < 0)
1153                  {
1154                    val.append('0');
1155                    point++;
1156                  }
1157                // Append the unscaled value.
1158                val.append(bigStr.substring(negative ? 1 : 0));
1159              }
1160            else
1161              {
1162                // No zeros need to be prepended so the String is simply the 
1163                // unscaled value with the decimal point inserted.
1164                val.append(bigStr);
1165                val.insert(point + (negative ? 1 : 0), '.');
1166              }
1167          }
1168        else
1169          {
1170            // We must use scientific notation to represent this BigDecimal.
1171            // The exponent must be a multiple of 3 and the integer part
1172            // must be between 1 and 999.
1173            val.append(bigStr);        
1174            int zeros = adjExp % 3;
1175            int dot = 1;
1176            if (adjExp > 0)
1177              {
1178                // If the exponent is positive we just move the decimal to the
1179                // right and decrease the exponent until it is a multiple of 3.
1180                dot += zeros;
1181                adjExp -= zeros;
1182              }
1183            else
1184              {
1185                // If the exponent is negative then we move the dot to the right
1186                // and decrease the exponent (increase its magnitude) until 
1187                // it is a multiple of 3.  Note that this is not adjExp -= zeros
1188                // because the mod operator doesn't give us the distance to the 
1189                // correct multiple of 3.  (-5 mod 3) is -2 but the distance from
1190                // -5 to the correct multiple of 3 (-6) is 1, not 2.
1191                if (zeros == -2)
1192                  {
1193                    dot += 1;
1194                    adjExp -= 1;
1195                  }
1196                else if (zeros == -1)
1197                  {
1198                    dot += 2;
1199                    adjExp -= 2;
1200                  }
1201              }
1202    
1203            // Either we have to append zeros because, for example, 1.1E+5 should
1204            // be 110E+3, or we just have to put the decimal in the right place.
1205            if (dot > val.length())
1206              {
1207                while (dot > val.length())
1208                  val.append('0');
1209              }
1210            else if (bigStr.length() > dot)
1211              val.insert(dot + (negative ? 1 : 0), '.');
1212            
1213            // And then append 'E' and the exponent (adjExp).
1214            val.append('E');
1215            if (adjExp >= 0)
1216              val.append('+');
1217            val.append(adjExp);
1218          }
1219        return val.toString();
1220      }
1221      
1222      /**
1223       * Returns a String representation of this BigDecimal without using 
1224       * scientific notation.  This is how toString() worked for releases 1.4
1225       * and previous.  Zeros may be added to the end of the String.  For
1226       * example, an unscaled value of 1234 and a scale of -3 would result in 
1227       * the String 1234000, but the toString() method would return 
1228       * 1.234E+6.
1229       * @return a String representation of this BigDecimal
1230       * @since 1.5
1231       */
1232      public String toPlainString()
1233      {
1234        // If the scale is zero we simply return the String representation of the 
1235        // unscaled value.
1236        String bigStr = intVal.toString();
1237        if (scale == 0)
1238          return bigStr;
1239    
1240        // Remember if we have to put a negative sign at the start.
1241        boolean negative = (bigStr.charAt(0) == '-');
1242    
1243        int point = bigStr.length() - scale - (negative ? 1 : 0);
1244    
1245        StringBuffer sb = new StringBuffer(bigStr.length() + 2
1246                                           + (point <= 0 ? (-point + 1) : 0));
1247        if (point <= 0)
1248          {
1249            // We have to prepend zeros and a decimal point.
1250            if (negative)
1251              sb.append('-');
1252            sb.append('0').append('.');
1253            while (point < 0)
1254              {
1255                sb.append('0');
1256                point++;
1257              }
1258            sb.append(bigStr.substring(negative ? 1 : 0));
1259          }
1260        else if (point < bigStr.length())
1261          {
1262            // No zeros need to be prepended or appended, just put the decimal
1263            // in the right place.
1264            sb.append(bigStr);
1265            sb.insert(point + (negative ? 1 : 0), '.');
1266          }
1267        else
1268          {
1269            // We must append zeros instead of using scientific notation.
1270            sb.append(bigStr);
1271            for (int i = bigStr.length(); i < point; i++)
1272              sb.append('0');
1273          }
1274        return sb.toString();
1275      }
1276      
1277      /**
1278       * Converts this BigDecimal to a BigInteger.  Any fractional part will
1279       * be discarded.
1280       * @return a BigDecimal whose value is equal to floor[this]
1281       */
1282      public BigInteger toBigInteger () 
1283      {
1284        // If scale > 0 then we must divide, if scale > 0 then we must multiply,
1285        // and if scale is zero then we just return intVal;
1286        if (scale > 0)
1287          return intVal.divide (BigInteger.TEN.pow (scale));
1288        else if (scale < 0)
1289          return intVal.multiply(BigInteger.TEN.pow(-scale));
1290        return intVal;
1291      }
1292      
1293      /**
1294       * Converts this BigDecimal into a BigInteger, throwing an 
1295       * ArithmeticException if the conversion is not exact.
1296       * @return a BigInteger whose value is equal to the value of this BigDecimal
1297       * @since 1.5
1298       */
1299      public BigInteger toBigIntegerExact()
1300      {
1301        if (scale > 0)
1302          {
1303            // If we have to divide, we must check if the result is exact.
1304            BigInteger[] result = 
1305              intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
1306            if (result[1].equals(BigInteger.ZERO))
1307              return result[0];
1308            throw new ArithmeticException("No exact BigInteger representation");
1309          }
1310        else if (scale < 0)
1311          // If we're multiplying instead, then we needn't check for exactness.
1312          return intVal.multiply(BigInteger.TEN.pow(-scale));
1313        // If the scale is zero we can simply return intVal.
1314        return intVal;
1315      }
1316    
1317      public int intValue () 
1318      {
1319        return toBigInteger ().intValue ();
1320      }
1321      
1322      /**
1323       * Returns a BigDecimal which is numerically equal to this BigDecimal but 
1324       * with no trailing zeros in the representation.  For example, if this 
1325       * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns
1326       * a BigDecimal with [unscaledValue, scale] = [6313, 1].  As another 
1327       * example, [12400, -2] would become [124, -4].
1328       * @return a numerically equal BigDecimal with no trailing zeros
1329       */
1330      public BigDecimal stripTrailingZeros()  
1331      {
1332        String intValStr = intVal.toString();
1333        int newScale = scale;
1334        int pointer = intValStr.length() - 1;
1335        // This loop adjusts pointer which will be used to give us the substring
1336        // of intValStr to use in our new BigDecimal, and also accordingly
1337        // adjusts the scale of our new BigDecimal.
1338        while (intValStr.charAt(pointer) == '0')
1339          {
1340            pointer --;
1341            newScale --;
1342          }
1343        // Create a new BigDecimal with the appropriate substring and then
1344        // set its scale.
1345        BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));    
1346        result.scale = newScale;
1347        return result;
1348      }
1349    
1350      public long longValue ()
1351      {
1352        return toBigInteger().longValue();
1353      }
1354    
1355      public float floatValue() 
1356      {
1357        return Float.valueOf(toString()).floatValue();
1358      }
1359    
1360      public double doubleValue() 
1361      {
1362        return Double.valueOf(toString()).doubleValue();
1363      }
1364    
1365      public BigDecimal setScale (int scale) throws ArithmeticException
1366      {
1367        return setScale (scale, ROUND_UNNECESSARY);
1368      }
1369    
1370      public BigDecimal setScale (int scale, int roundingMode)
1371        throws ArithmeticException, IllegalArgumentException
1372      {
1373        // NOTE: The 1.5 JRE doesn't throw this, ones prior to it do and
1374        // the spec says it should. Nevertheless, if 1.6 doesn't fix this
1375        // we should consider removing it.
1376        if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
1377        return divide (ONE, scale, roundingMode);
1378      }
1379      
1380      /**
1381       * Returns a BigDecimal whose value is the same as this BigDecimal but whose
1382       * representation has a scale of <code>newScale</code>.  If the scale is
1383       * reduced then rounding may occur, according to the RoundingMode.
1384       * @param newScale
1385       * @param roundingMode
1386       * @return a BigDecimal whose scale is as given, whose value is 
1387       * <code>this</code> with possible rounding
1388       * @throws ArithmeticException if the rounding mode is UNNECESSARY but 
1389       * rounding is required 
1390       * @since 1.5
1391       */
1392      public BigDecimal setScale(int newScale, RoundingMode roundingMode)
1393      {
1394        return setScale(newScale, roundingMode.ordinal());
1395      }
1396      
1397      /**
1398       * Returns a new BigDecimal constructed from the BigDecimal(String) 
1399       * constructor using the Double.toString(double) method to obtain
1400       * the String.
1401       * @param val the double value used in Double.toString(double)
1402       * @return a BigDecimal representation of val
1403       * @throws NumberFormatException if val is NaN or infinite
1404       * @since 1.5
1405       */
1406      public static BigDecimal valueOf(double val)
1407      {
1408        if (Double.isInfinite(val) || Double.isNaN(val))
1409          throw new NumberFormatException("argument cannot be NaN or infinite.");
1410        return new BigDecimal(Double.toString(val));
1411      }
1412      
1413      /**
1414       * Returns a BigDecimal whose numerical value is the numerical value
1415       * of this BigDecimal multiplied by 10 to the power of <code>n</code>. 
1416       * @param n the power of ten
1417       * @return the new BigDecimal
1418       * @since 1.5
1419       */
1420      public BigDecimal scaleByPowerOfTen(int n)
1421      {
1422        BigDecimal result = new BigDecimal(intVal, scale - n);
1423        result.precision = precision;
1424        return result;
1425      }
1426      
1427      /**
1428       * Returns a BigDecimal whose value is <code>this</code> to the power of 
1429       * <code>n</code>. 
1430       * @param n the power
1431       * @return the new BigDecimal
1432       * @since 1.5
1433       */
1434      public BigDecimal pow(int n)
1435      {
1436        if (n < 0 || n > 999999999)
1437          throw new ArithmeticException("n must be between 0 and 999999999");
1438        BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
1439        return result;
1440      }
1441      
1442      /**
1443       * Returns a BigDecimal whose value is determined by first calling pow(n)
1444       * and then by rounding according to the MathContext mc.
1445       * @param n the power
1446       * @param mc the MathContext
1447       * @return the new BigDecimal
1448       * @throws ArithmeticException if n < 0 or n > 999999999 or if the result is
1449       * inexact but the rounding is RoundingMode.UNNECESSARY
1450       * @since 1.5
1451       */
1452      public BigDecimal pow(int n, MathContext mc)
1453      {
1454        // FIXME: The specs claim to use the X3.274-1996 algorithm.  We
1455        // currently do not.
1456        return pow(n).round(mc);
1457      }
1458      
1459      /**
1460       * Returns a BigDecimal whose value is the absolute value of this BigDecimal
1461       * with rounding according to the given MathContext.
1462       * @param mc the MathContext
1463       * @return the new BigDecimal
1464       */
1465      public BigDecimal abs(MathContext mc)
1466      {
1467        BigDecimal result = abs();
1468        result = result.round(mc);
1469        return result;
1470      }
1471      
1472      /**
1473       * Returns the size of a unit in the last place of this BigDecimal.  This
1474       * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()].
1475       * @return the size of a unit in the last place of <code>this</code>.
1476       * @since 1.5
1477       */
1478      public BigDecimal ulp()
1479      {
1480        return new BigDecimal(BigInteger.ONE, scale);
1481      }
1482      
1483      /**
1484       * Converts this BigDecimal to a long value.
1485       * @return the long value
1486       * @throws ArithmeticException if rounding occurs or if overflow occurs
1487       * @since 1.5
1488       */
1489      public long longValueExact()
1490      {
1491        // Set scale will throw an exception if rounding occurs.
1492        BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
1493        BigInteger tempVal = temp.intVal;
1494        // Check for overflow.
1495        long result = intVal.longValue();
1496        if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
1497            || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
1498          throw new ArithmeticException("this BigDecimal is too " +
1499                "large to fit into the return type");
1500        
1501        return intVal.longValue();
1502      }
1503      
1504      /**
1505       * Converts this BigDecimal into an int by first calling longValueExact
1506       * and then checking that the <code>long</code> returned from that
1507       * method fits into an <code>int</code>.
1508       * @return an int whose value is <code>this</code>
1509       * @throws ArithmeticException if this BigDecimal has a fractional part
1510       * or is too large to fit into an int.
1511       * @since 1.5
1512       */
1513      public int intValueExact()
1514      {
1515        long temp = longValueExact();
1516        int result = (int)temp;
1517        if (result != temp)
1518          throw new ArithmeticException ("this BigDecimal cannot fit into an int");
1519        return result;
1520      }
1521      
1522      /**
1523       * Converts this BigDecimal into a byte by first calling longValueExact
1524       * and then checking that the <code>long</code> returned from that
1525       * method fits into a <code>byte</code>.
1526       * @return a byte whose value is <code>this</code>
1527       * @throws ArithmeticException if this BigDecimal has a fractional part
1528       * or is too large to fit into a byte.
1529       * @since 1.5
1530       */
1531      public byte byteValueExact()
1532      {
1533        long temp = longValueExact();
1534        byte result = (byte)temp;
1535        if (result != temp)
1536          throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
1537        return result;
1538      }
1539      
1540      /**
1541       * Converts this BigDecimal into a short by first calling longValueExact
1542       * and then checking that the <code>long</code> returned from that
1543       * method fits into a <code>short</code>.
1544       * @return a short whose value is <code>this</code>
1545       * @throws ArithmeticException if this BigDecimal has a fractional part
1546       * or is too large to fit into a short.
1547       * @since 1.5
1548       */
1549      public short shortValueExact()
1550      {
1551        long temp = longValueExact();
1552        short result = (short)temp;
1553        if (result != temp)
1554          throw new ArithmeticException ("this BigDecimal cannot fit into a short");
1555        return result;
1556      }
1557    }