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