Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.math.BigDecimal

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

AltStyle によって変換されたページ (->オリジナル) /