OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / math / BigDecimal.java
1 /* java.math.BigDecimal -- Arbitrary precision decimals.
2    Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package java.math;
39
40 import gnu.java.lang.CPStringBuilder;
41
42 public class BigDecimal extends Number implements Comparable<BigDecimal>
43 {
44   private BigInteger intVal;
45   private int scale;
46   private int precision = 0;
47   private static final long serialVersionUID = 6108874887143696463L;
48
49   /**
50    * The constant zero as a BigDecimal with scale zero.
51    * @since 1.5
52    */
53   public static final BigDecimal ZERO = 
54     new BigDecimal (BigInteger.ZERO, 0);
55
56   /**
57    * The constant one as a BigDecimal with scale zero.
58    * @since 1.5
59    */
60   public static final BigDecimal ONE = 
61     new BigDecimal (BigInteger.ONE, 0);
62
63   /**
64    * The constant ten as a BigDecimal with scale zero.
65    * @since 1.5
66    */
67   public static final BigDecimal TEN = 
68     new BigDecimal (BigInteger.TEN, 0);
69
70   public static final int ROUND_UP = 0;
71   public static final int ROUND_DOWN = 1;
72   public static final int ROUND_CEILING = 2;
73   public static final int ROUND_FLOOR = 3;
74   public static final int ROUND_HALF_UP = 4;
75   public static final int ROUND_HALF_DOWN = 5;
76   public static final int ROUND_HALF_EVEN = 6;
77   public static final int ROUND_UNNECESSARY = 7;
78
79   /**
80    * Constructs a new BigDecimal whose unscaled value is val and whose
81    * scale is zero.
82    * @param val the value of the new BigDecimal
83    * @since 1.5
84    */
85   public BigDecimal (int val)
86   {
87     this.intVal = BigInteger.valueOf(val);
88     this.scale = 0;
89   }
90   
91   /**
92    * Constructs a BigDecimal using the BigDecimal(int) constructor and then
93    * rounds according to the MathContext.
94    * @param val the value for the initial (unrounded) BigDecimal
95    * @param mc the MathContext specifying the rounding
96    * @throws ArithmeticException if the result is inexact but the rounding type
97    * is RoundingMode.UNNECESSARY
98    * @since 1.5
99    */
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 }