OSDN Git Service

Merged gcj-eclipse branch to trunk.
[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 public class BigDecimal extends Number implements Comparable<BigDecimal>
41 {
42   private BigInteger intVal;
43   private int scale;
44   private int precision = 0;
45   private static final long serialVersionUID = 6108874887143696463L;
46
47   /**
48    * The constant zero as a BigDecimal with scale zero.
49    * @since 1.5
50    */
51   public static final BigDecimal ZERO = 
52     new BigDecimal (BigInteger.ZERO, 0);
53
54   /**
55    * The constant one as a BigDecimal with scale zero.
56    * @since 1.5
57    */
58   public static final BigDecimal ONE = 
59     new BigDecimal (BigInteger.ONE, 0);
60
61   /**
62    * The constant ten as a BigDecimal with scale zero.
63    * @since 1.5
64    */
65   public static final BigDecimal TEN = 
66     new BigDecimal (BigInteger.TEN, 0);
67
68   public static final int ROUND_UP = 0;
69   public static final int ROUND_DOWN = 1;
70   public static final int ROUND_CEILING = 2;
71   public static final int ROUND_FLOOR = 3;
72   public static final int ROUND_HALF_UP = 4;
73   public static final int ROUND_HALF_DOWN = 5;
74   public static final int ROUND_HALF_EVEN = 6;
75   public static final int ROUND_UNNECESSARY = 7;
76
77   /**
78    * Constructs a new BigDecimal whose unscaled value is val and whose
79    * scale is zero.
80    * @param val the value of the new BigDecimal
81    * @since 1.5
82    */
83   public BigDecimal (int val)
84   {
85     this.intVal = BigInteger.valueOf(val);
86     this.scale = 0;
87   }
88   
89   /**
90    * Constructs a BigDecimal using the BigDecimal(int) constructor and then
91    * rounds according to the MathContext.
92    * @param val the value for the initial (unrounded) BigDecimal
93    * @param mc the MathContext specifying the rounding
94    * @throws ArithmeticException if the result is inexact but the rounding type
95    * is RoundingMode.UNNECESSARY
96    * @since 1.5
97    */
98   public BigDecimal (int val, MathContext mc)
99   {
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 }