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 }