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