0001: /*
0002: * @(#)BigDecimal.java 1.48 06/10/17
0003: *
0004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: */
0026:
0027: package java.math;
0028:
0029: /**
0030: * Immutable, arbitrary-precision signed decimal numbers. A BigDecimal
0031: * consists of an arbitrary precision integer <i>unscaled value</i> and a
0032: * non-negative 32-bit integer <i>scale</i>, which represents the number of
0033: * digits to the right of the decimal point. The number represented by the
0034: * BigDecimal is <tt>(unscaledValue/10<sup>scale</sup>)</tt>. BigDecimal
0035: * provides operations for basic arithmetic, scale manipulation, comparison,
0036: * hashing, and format conversion.
0037: * <p>
0038: * The BigDecimal class gives its user complete control over rounding
0039: * behavior, forcing the user to explicitly specify a rounding
0040: * behavior for operations capable of discarding precision ({@link
0041: * #divide(BigDecimal, int)}, {@link #divide(BigDecimal, int, int)},
0042: * and {@link #setScale}). Eight <em>rounding modes</em> are provided
0043: * for this purpose.
0044: * <p>
0045: * Two types of operations are provided for manipulating the scale of a
0046: * BigDecimal: scaling/rounding operations and decimal point motion
0047: * operations. Scaling/rounding operations (<tt>setScale</tt>) return a
0048: * BigDecimal whose value is approximately (or exactly) equal to that of the
0049: * operand, but whose scale is the specified value; that is, they increase or
0050: * decrease the precision of the number with minimal effect on its value.
0051: * Decimal point motion operations ({@link #movePointLeft} and
0052: * {@link #movePointRight}) return a BigDecimal created from the operand by
0053: * moving the decimal point a specified distance in the specified direction;
0054: * that is, they change a number's value without affecting its precision.
0055: * <p>
0056: * For the sake of brevity and clarity, pseudo-code is used throughout the
0057: * descriptions of BigDecimal methods. The pseudo-code expression
0058: * <tt>(i + j)</tt> is shorthand for "a BigDecimal whose value is
0059: * that of the BigDecimal <tt>i</tt> plus that of the BigDecimal <tt>j</tt>."
0060: * The pseudo-code expression <tt>(i == j)</tt> is shorthand for
0061: * "<tt>true</tt> if and only if the BigDecimal <tt>i</tt> represents the same
0062: * value as the the BigDecimal <tt>j</tt>." Other pseudo-code expressions are
0063: * interpreted similarly.
0064: * <p>
0065: * Note: care should be exercised if BigDecimals are to be used as
0066: * keys in a {@link java.util.SortedMap} or elements in a {@link
0067: * java.util.SortedSet}, as BigDecimal's <i>natural ordering</i> is
0068: * <i>inconsistent with equals</i>. See {@link Comparable}, {@link
0069: * java.util.SortedMap} or {@link java.util.SortedSet} for more
0070: * information.
0071: * <p>
0072: * All methods and constructors for this class
0073: * throw <CODE>NullPointerException</CODE> when passed
0074: * a null object reference for any input parameter.
0075: *
0076: * @see BigInteger
0077: * @see java.util.SortedMap
0078: * @see java.util.SortedSet
0079: * @version 1.33, 08/19/02
0080: * @author Josh Bloch
0081: */
0082: public class BigDecimal extends Number implements Comparable {
0083: /**
0084: * The unscaled value of this BigDecimal, as returned by unscaledValue().
0085: *
0086: * @serial
0087: * @see #unscaledValue
0088: */
0089: private BigInteger intVal;
0090: /**
0091: * The scale of this BigDecimal, as returned by scale().
0092: *
0093: * @serial
0094: * @see #scale
0095: */
0096: private int scale = 0;
0097: /* Appease the serialization gods */
0098: private static final long serialVersionUID = 6108874887143696463L;
0099:
0100: // Constructors
0101:
0102: /**
0103: * Translates the String representation of a BigDecimal into a
0104: * BigDecimal. The String representation consists of an optional
0105: * sign, <tt>'+'</tt> (<tt>'\u002B'</tt>) or <tt>'-'</tt>
0106: * (<tt>'\u002D'</tt>), followed by a sequence of zero or more
0107: * decimal digits ("the integer"), optionally followed by a
0108: * fraction, optionally followed by an exponent.
0109: *
0110: * <p>The fraction consists of of a decimal point followed by zero or more
0111: * decimal digits. The string must contain at least one digit in either
0112: * the integer or the fraction. The number formed by the sign, the
0113: * integer and the fraction is referred to as the <i>significand</i>.
0114: *
0115: * <p>The exponent consists of the character <tt>'e'</tt>
0116: * (<tt>'\u0075'</tt>) or <tt>'E'</tt> (<tt>'\u0045'</tt>)
0117: * followed by one or more decimal digits. The value of the
0118: * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
0119: * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
0120: *
0121: * <p>More formally, the strings this constructor accepts are
0122: * described by the following grammar:
0123: * <blockquote>
0124: * <dl>
0125: * <dt><i>BigDecimalString:</i>
0126: * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
0127: * <p>
0128: * <dt><i>Sign:</i>
0129: * <dd><code>+</code>
0130: * <dd><code>-</code>
0131: * <p>
0132: * <dt><i>Significand:</i>
0133: * <dd><i>IntegerPart</i> <code>.</code> <i>FractionPart<sub>opt</sub></i>
0134: * <dd><code>.</code> <i>FractionPart</i>
0135: * <dd><i>IntegerPart</i>
0136: * <p>
0137: * <dt><i>IntegerPart:
0138: * <dd>Digits</i>
0139: * <p>
0140: * <dt><i>FractionPart:
0141: * <dd>Digits</i>
0142: * <p>
0143: * <dt><i>Exponent:
0144: * <dd>ExponentIndicator SignedInteger</i>
0145: * <p>
0146: * <dt><i>ExponentIndicator:</i>
0147: * <dd><code>e</code>
0148: * <dd><code>E</code>
0149: * <p>
0150: * <dt><i>SignedInteger:
0151: * <dd>Sign<sub>opt</sub> Digits</i>
0152: * <p>
0153: * <dt><i>Digits:
0154: * <dd>Digit
0155: * <dd>Digits Digit</i>
0156: * <p>
0157: * <dt><i>Digit:</i>
0158: * <dd>any character for which {@link Character#isDigit}
0159: * returns <code>true</code>, including 0, 1, 2 ...
0160: * </dl>
0161: * </blockquote>
0162: *
0163: * <p>The scale of the returned BigDecimal will be the number of digits in
0164: * the fraction, or zero if the string contains no decimal point, subject
0165: * to adjustment for any exponent: If the string contains an exponent, the
0166: * exponent is subtracted from the scale. If the resulting scale is
0167: * negative, the scale of the returned BigDecimal is zero and the unscaled
0168: * value is multiplied by the appropriate power of ten so that, in every
0169: * case, the resulting BigDecimal is equal to <i>significand</i> ×
0170: * 10<i><sup>exponent</sup></i>. (If in the future this specification is
0171: * amended to permit negative scales, the final step of zeroing the scale
0172: * and adjusting the unscaled value will be eliminated.)
0173: *
0174: * <p>The character-to-digit mapping is provided by {@link
0175: * java.lang.Character#digit} set to convert to radix 10. The
0176: * String may not contain any extraneous characters (whitespace,
0177: * for example).
0178: *
0179: * <p>Note: For values other <tt>float</tt> and <tt>double</tt>
0180: * NaN and ±Infinity, this constructor is compatible with
0181: * the values returned by {@link Float#toString} and {@link
0182: * Double#toString}. This is generally the preferred way to
0183: * convert a <tt>float</tt> or <tt>double</tt> into a BigDecimal,
0184: * as it doesn't suffer from the unpredictability of the {@link
0185: * #BigDecimal(double)} constructor.
0186: *
0187: * <p>Note: the optional leading plus sign and trailing exponent were
0188: * added in release 1.3.
0189: *
0190: * @param val String representation of BigDecimal.
0191: * @throws NumberFormatException <tt>val</tt> is not a valid representation
0192: * of a BigDecimal.
0193: */
0194: public BigDecimal(String val) {
0195: // Empty string not accepted
0196: if (val.length() == 0)
0197: throw new NumberFormatException();
0198:
0199: // Deal with leading plus sign if present
0200: if (val.charAt(0) == '+') {
0201: val = val.substring(1); /* Discard leading '+' */
0202: if (val.length() == 0 || /* "+" illegal! */
0203: val.charAt(0) == '-') /* "+-123.456" illegal! */
0204: throw new NumberFormatException();
0205: }
0206: // If exponent is present, break into exponent and significand
0207: int exponent = 0;
0208: int ePos = val.indexOf('e');
0209: if (ePos == -1)
0210: ePos = val.indexOf('E');
0211: if (ePos != -1) {
0212: String exp = val.substring(ePos + 1);
0213: if (exp.length() == 0) /* "1.2e" illegal! */
0214: throw new NumberFormatException();
0215: if (exp.charAt(0) == '+') {
0216: exp = exp.substring(1); /* Discard leading '+' */
0217: if (exp.length() == 0 || /* "123.456e+" illegal! */
0218: exp.charAt(0) == '-') /* "123.456e+-7" illegal! */
0219: throw new NumberFormatException();
0220: }
0221: exponent = Integer.parseInt(exp);
0222: if (ePos == 0)
0223: throw new NumberFormatException(); /* "e123" illegal! */
0224: val = val.substring(0, ePos);
0225: }
0226: // Parse significand
0227: int pointPos = val.indexOf('.');
0228: if (pointPos == -1) { /* e.g. "123" */
0229: intVal = new BigInteger(val);
0230: } else if (pointPos == val.length() - 1) { /* e.g. "123." */
0231: intVal = new BigInteger(val.substring(0, val.length() - 1));
0232: } else { /* Fraction part exists */
0233: if (val.charAt(pointPos + 1) == '-') /* ".-123" illegal! */
0234: throw new NumberFormatException();
0235:
0236: char[] digits = new char[val.length() - 1];
0237: // Get chars before decimal point
0238: val.getChars(0, pointPos, digits, 0);
0239: // Get chars after decimal point
0240: val.getChars(pointPos + 1, val.length(), digits, pointPos);
0241: scale = val.length() - pointPos - 1;
0242: intVal = new BigInteger(digits);
0243: }
0244:
0245: // Combine exponent into significand
0246: if (sun.misc.BuildFlags.qAssertsEnabled)
0247: assert (scale >= 0); // && scale <= Integer.MAX_VALUE
0248: long longScale = (long) scale - (long) exponent; // Avoid errors
0249: // in calculating scale
0250: if (longScale > Integer.MAX_VALUE)
0251: throw new NumberFormatException("Final scale out of range");
0252: scale = (int) longScale;
0253: if (sun.misc.BuildFlags.qAssertsEnabled)
0254: assert (scale == longScale && // conversion should be exact
0255: Math.abs(longScale) <= Integer.MAX_VALUE) // exponent range
0256: // check
0257: : longScale;
0258: if (scale < 0) {
0259: intVal = timesTenToThe(intVal, -scale);
0260: scale = 0;
0261: }
0262: }
0263:
0264: /**
0265: * Translates a <code>double</code> into a BigDecimal. The scale
0266: * of the BigDecimal is the smallest value such that
0267: * <tt>(10<sup>scale</sup> * val)</tt> is an integer.
0268: * <p>
0269: * Note: the results of this constructor can be somewhat unpredictable.
0270: * One might assume that <tt>new BigDecimal(.1)</tt> is exactly equal
0271: * to .1, but it is actually equal
0272: * to .1000000000000000055511151231257827021181583404541015625.
0273: * This is so because .1 cannot be represented exactly as a double
0274: * (or, for that matter, as a binary fraction of any finite length).
0275: * Thus, the long value that is being passed <i>in</i> to the constructor
0276: * is not exactly equal to .1, appearances notwithstanding.
0277: * <p>
0278: * The (String) constructor, on the other hand, is perfectly predictable:
0279: * <tt>new BigDecimal(".1")</tt> is <i>exactly</i> equal to .1, as one
0280: * would expect. Therefore, it is generally recommended that the (String)
0281: * constructor be used in preference to this one.
0282: *
0283: * @param val <code>double</code> value to be converted to BigDecimal.
0284: * @throws NumberFormatException <tt>val</tt> if <tt>val</tt> is
0285: * infinite or NaN.
0286: */
0287: public BigDecimal(double val) {
0288: if (Double.isInfinite(val) || Double.isNaN(val))
0289: throw new NumberFormatException("Infinite or NaN");
0290: /*
0291: * Translate the double into sign, exponent and mantissa, according
0292: * to the formulae in JLS, Section 20.10.22.
0293: */
0294: long valBits = Double.doubleToLongBits(val);
0295: int sign = ((valBits >> 63) == 0 ? 1 : -1);
0296: int exponent = (int) ((valBits >> 52) & 0x7ffL);
0297: long mantissa = (exponent == 0 ? (valBits & ((1L << 52) - 1)) << 1
0298: : (valBits & ((1L << 52) - 1)) | (1L << 52));
0299: exponent -= 1075;
0300: /* At this point, val == sign * mantissa * 2**exponent */
0301:
0302: /*
0303: * Special case zero to to supress nonterminating normalization
0304: * and bogus scale calculation.
0305: */
0306: if (mantissa == 0) {
0307: intVal = BigInteger.ZERO;
0308: return;
0309: }
0310: /* Normalize */
0311: while ((mantissa & 1) == 0) { /* i.e., Mantissa is even */
0312: mantissa >>= 1;
0313: exponent++;
0314: }
0315: /* Calculate intVal and scale */
0316: intVal = BigInteger.valueOf(sign * mantissa);
0317: if (exponent < 0) {
0318: intVal = intVal.multiply(BigInteger.valueOf(5).pow(
0319: -exponent));
0320: scale = -exponent;
0321: } else if (exponent > 0) {
0322: intVal = intVal.multiply(BigInteger.valueOf(2)
0323: .pow(exponent));
0324: }
0325: }
0326:
0327: /**
0328: * Translates a BigInteger into a BigDecimal. The scale of the BigDecimal
0329: * is zero.
0330: *
0331: * @param val BigInteger value to be converted to BigDecimal.
0332: */
0333: public BigDecimal(BigInteger val) {
0334: intVal = val;
0335: }
0336:
0337: /**
0338: * Translates a BigInteger unscaled value and an <code>int</code>
0339: * scale into a BigDecimal. The value of the BigDecimal is
0340: * <tt>(unscaledVal/10<sup>scale</sup>)</tt>.
0341: *
0342: * @param unscaledVal unscaled value of the BigDecimal.
0343: * @param scale scale of the BigDecimal.
0344: * @throws NumberFormatException scale is negative
0345: */
0346: public BigDecimal(BigInteger unscaledVal, int scale) {
0347: if (scale < 0)
0348: throw new NumberFormatException("Negative scale");
0349: intVal = unscaledVal;
0350: this .scale = scale;
0351: }
0352:
0353: // Static Factory Methods
0354:
0355: /**
0356: * Translates a <code>long</code> unscaled value and an
0357: * <code>int</code> scale into a BigDecimal. This "static factory
0358: * method" is provided in preference to a (<code>long</code>,
0359: * <code>int</code>) constructor because it allows for reuse of
0360: * frequently used BigDecimals.
0361: *
0362: * @param unscaledVal unscaled value of the BigDecimal.
0363: * @param scale scale of the BigDecimal.
0364: * @return a BigDecimal whose value is
0365: * <tt>(unscaledVal/10<sup>scale</sup>)</tt>.
0366: */
0367: public static BigDecimal valueOf(long unscaledVal, int scale) {
0368: return new BigDecimal(BigInteger.valueOf(unscaledVal), scale);
0369: }
0370:
0371: /**
0372: * Translates a <code>long</code> value into a BigDecimal with a
0373: * scale of zero. This "static factory method" is provided in
0374: * preference to a (<code>long</code>) constructor because it
0375: * allows for reuse of frequently used BigDecimals.
0376: *
0377: * @param val value of the BigDecimal.
0378: * @return a BigDecimal whose value is <tt>val</tt>.
0379: */
0380: public static BigDecimal valueOf(long val) {
0381: return valueOf(val, 0);
0382: }
0383:
0384: // Arithmetic Operations
0385:
0386: /**
0387: * Returns a BigDecimal whose value is <tt>(this + val)</tt>, and whose
0388: * scale is <tt>max(this.scale(), val.scale())</tt>.
0389: *
0390: * @param val value to be added to this BigDecimal.
0391: * @return <tt>this + val</tt>
0392: */
0393: public BigDecimal add(BigDecimal val) {
0394: BigDecimal arg[] = new BigDecimal[2];
0395: arg[0] = this ;
0396: arg[1] = val;
0397: matchScale(arg);
0398: return new BigDecimal(arg[0].intVal.add(arg[1].intVal),
0399: arg[0].scale);
0400: }
0401:
0402: /**
0403: * Returns a BigDecimal whose value is <tt>(this - val)</tt>, and whose
0404: * scale is <tt>max(this.scale(), val.scale())</tt>.
0405: *
0406: * @param val value to be subtracted from this BigDecimal.
0407: * @return <tt>this - val</tt>
0408: */
0409: public BigDecimal subtract(BigDecimal val) {
0410: BigDecimal arg[] = new BigDecimal[2];
0411: arg[0] = this ;
0412: arg[1] = val;
0413: matchScale(arg);
0414: return new BigDecimal(arg[0].intVal.subtract(arg[1].intVal),
0415: arg[0].scale);
0416: }
0417:
0418: /**
0419: * Returns a BigDecimal whose value is <tt>(this * val)</tt>, and whose
0420: * scale is <tt>(this.scale() + val.scale())</tt>.
0421: *
0422: * @param val value to be multiplied by this BigDecimal.
0423: * @return <tt>this * val</tt>
0424: */
0425: public BigDecimal multiply(BigDecimal val) {
0426: return new BigDecimal(intVal.multiply(val.intVal), scale
0427: + val.scale);
0428: }
0429:
0430: /**
0431: * Returns a BigDecimal whose value is <tt>(this / val)</tt>, and whose
0432: * scale is as specified. If rounding must be performed to generate a
0433: * result with the specified scale, the specified rounding mode is
0434: * applied.
0435: *
0436: * @param val value by which this BigDecimal is to be divided.
0437: * @param scale scale of the BigDecimal quotient to be returned.
0438: * @param roundingMode rounding mode to apply.
0439: * @return <tt>this / val</tt>
0440: * @throws ArithmeticException <tt>val</tt> is zero, <tt>scale</tt> is
0441: * negative, or <tt>roundingMode==ROUND_UNNECESSARY</tt> and
0442: * the specified scale is insufficient to represent the result
0443: * of the division exactly.
0444: * @throws IllegalArgumentException <tt>roundingMode</tt> does not
0445: * represent a valid rounding mode.
0446: * @see #ROUND_UP
0447: * @see #ROUND_DOWN
0448: * @see #ROUND_CEILING
0449: * @see #ROUND_FLOOR
0450: * @see #ROUND_HALF_UP
0451: * @see #ROUND_HALF_DOWN
0452: * @see #ROUND_HALF_EVEN
0453: * @see #ROUND_UNNECESSARY
0454: */
0455: public BigDecimal divide(BigDecimal val, int scale, int roundingMode) {
0456: if (scale < 0)
0457: throw new ArithmeticException("Negative scale");
0458: if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
0459: throw new IllegalArgumentException("Invalid rounding mode");
0460: /*
0461: * Rescale dividend or divisor (whichever can be "upscaled" to
0462: * produce correctly scaled quotient).
0463: */
0464: BigDecimal dividend, divisor;
0465: if (scale + val.scale >= this .scale) {
0466: dividend = this .setScale(scale + val.scale);
0467: divisor = val;
0468: } else {
0469: dividend = this ;
0470: divisor = val.setScale(this .scale - scale);
0471: }
0472: /* Do the division and return result if it's exact */
0473: BigInteger i[] = dividend.intVal
0474: .divideAndRemainder(divisor.intVal);
0475: BigInteger q = i[0], r = i[1];
0476: if (r.signum() == 0)
0477: return new BigDecimal(q, scale);
0478: else if (roundingMode == ROUND_UNNECESSARY) /* Rounding prohibited */
0479: throw new ArithmeticException("Rounding necessary");
0480: /* Round as appropriate */
0481: int signum = dividend.signum() * divisor.signum(); /* Sign of result */
0482: boolean increment;
0483: if (roundingMode == ROUND_UP) { /* Away from zero */
0484: increment = true;
0485: } else if (roundingMode == ROUND_DOWN) { /* Towards zero */
0486: increment = false;
0487: } else if (roundingMode == ROUND_CEILING) { /* Towards +infinity */
0488: increment = (signum > 0);
0489: } else if (roundingMode == ROUND_FLOOR) { /* Towards -infinity */
0490: increment = (signum < 0);
0491: } else { /* Remaining modes based on nearest-neighbor determination */
0492: int cmpFracHalf = r.abs().multiply(BigInteger.valueOf(2))
0493: .compareTo(divisor.intVal.abs());
0494: if (cmpFracHalf < 0) { /* We're closer to higher digit */
0495: increment = false;
0496: } else if (cmpFracHalf > 0) { /* We're closer to lower digit */
0497: increment = true;
0498: } else { /* We're dead-center */
0499: if (roundingMode == ROUND_HALF_UP)
0500: increment = true;
0501: else if (roundingMode == ROUND_HALF_DOWN)
0502: increment = false;
0503: else
0504: /* roundingMode == ROUND_HALF_EVEN */
0505: increment = q.testBit(0); /* true iff q is odd */
0506: }
0507: }
0508: return (increment ? new BigDecimal(q.add(BigInteger
0509: .valueOf(signum)), scale) : new BigDecimal(q, scale));
0510: }
0511:
0512: /**
0513: * Returns a BigDecimal whose value is <tt>(this / val)</tt>, and whose
0514: * scale is <tt>this.scale()</tt>. If rounding must be performed to
0515: * generate a result with the given scale, the specified rounding mode is
0516: * applied.
0517: *
0518: * @param val value by which this BigDecimal is to be divided.
0519: * @param roundingMode rounding mode to apply.
0520: * @return <tt>this / val</tt>
0521: * @throws ArithmeticException <tt>val==0</tt>, or
0522: * <tt>roundingMode==ROUND_UNNECESSARY</tt> and
0523: * <tt>this.scale()</tt> is insufficient to represent the result
0524: * of the division exactly.
0525: * @throws IllegalArgumentException <tt>roundingMode</tt> does not
0526: * represent a valid rounding mode.
0527: * @see #ROUND_UP
0528: * @see #ROUND_DOWN
0529: * @see #ROUND_CEILING
0530: * @see #ROUND_FLOOR
0531: * @see #ROUND_HALF_UP
0532: * @see #ROUND_HALF_DOWN
0533: * @see #ROUND_HALF_EVEN
0534: * @see #ROUND_UNNECESSARY
0535: */
0536: public BigDecimal divide(BigDecimal val, int roundingMode) {
0537: return this .divide(val, scale, roundingMode);
0538: }
0539:
0540: /**
0541: * Returns a BigDecimal whose value is the absolute value of this
0542: * BigDecimal, and whose scale is <tt>this.scale()</tt>.
0543: *
0544: * @return <tt>abs(this)</tt>
0545: */
0546: public BigDecimal abs() {
0547: return (signum() < 0 ? negate() : this );
0548: }
0549:
0550: /**
0551: * Returns a BigDecimal whose value is <tt>(-this)</tt>, and whose scale
0552: * is <tt>this.scale()</tt>.
0553: *
0554: * @return <tt>-this</tt>
0555: */
0556: public BigDecimal negate() {
0557: return new BigDecimal(intVal.negate(), scale);
0558: }
0559:
0560: /**
0561: * Returns the signum function of this BigDecimal.
0562: *
0563: * @return -1, 0 or 1 as the value of this BigDecimal is negative, zero or
0564: * positive.
0565: */
0566: public int signum() {
0567: return intVal.signum();
0568: }
0569:
0570: /**
0571: * Returns the <i>scale</i> of this BigDecimal. (The scale is the number
0572: * of digits to the right of the decimal point.)
0573: *
0574: * @return the scale of this BigDecimal.
0575: */
0576: public int scale() {
0577: return scale;
0578: }
0579:
0580: /**
0581: * Returns a BigInteger whose value is the <i>unscaled value</i> of this
0582: * BigDecimal. (Computes <tt>(this * 10<sup>this.scale()</sup>)</tt>.)
0583: *
0584: * @return the unscaled value of this BigDecimal.
0585: * @since 1.2
0586: */
0587: public BigInteger unscaledValue() {
0588: return intVal;
0589: }
0590:
0591: // Rounding Modes
0592:
0593: /**
0594: * Rounding mode to round away from zero. Always increments the
0595: * digit prior to a non-zero discarded fraction. Note that this rounding
0596: * mode never decreases the magnitude of the calculated value.
0597: */
0598: public final static int ROUND_UP = 0;
0599: /**
0600: * Rounding mode to round towards zero. Never increments the digit
0601: * prior to a discarded fraction (i.e., truncates). Note that this
0602: * rounding mode never increases the magnitude of the calculated value.
0603: */
0604: public final static int ROUND_DOWN = 1;
0605: /**
0606: * Rounding mode to round towards positive infinity. If the
0607: * BigDecimal is positive, behaves as for <tt>ROUND_UP</tt>; if negative,
0608: * behaves as for <tt>ROUND_DOWN</tt>. Note that this rounding mode never
0609: * decreases the calculated value.
0610: */
0611: public final static int ROUND_CEILING = 2;
0612: /**
0613: * Rounding mode to round towards negative infinity. If the
0614: * BigDecimal is positive, behave as for <tt>ROUND_DOWN</tt>; if negative,
0615: * behave as for <tt>ROUND_UP</tt>. Note that this rounding mode never
0616: * increases the calculated value.
0617: */
0618: public final static int ROUND_FLOOR = 3;
0619: /**
0620: * Rounding mode to round towards "nearest neighbor" unless both
0621: * neighbors are equidistant, in which case round up.
0622: * Behaves as for <tt>ROUND_UP</tt> if the discarded fraction is >= .5;
0623: * otherwise, behaves as for <tt>ROUND_DOWN</tt>. Note that this is the
0624: * rounding mode that most of us were taught in grade school.
0625: */
0626: public final static int ROUND_HALF_UP = 4;
0627: /**
0628: * Rounding mode to round towards "nearest neighbor" unless both
0629: * neighbors are equidistant, in which case round down.
0630: * Behaves as for <tt>ROUND_UP</tt> if the discarded fraction is > .5;
0631: * otherwise, behaves as for <tt>ROUND_DOWN</tt>.
0632: */
0633: public final static int ROUND_HALF_DOWN = 5;
0634: /**
0635: * Rounding mode to round towards the "nearest neighbor" unless both
0636: * neighbors are equidistant, in which case, round towards the even
0637: * neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the
0638: * discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even.
0639: * Note that this is the rounding mode that minimizes cumulative error
0640: * when applied repeatedly over a sequence of calculations.
0641: */
0642: public final static int ROUND_HALF_EVEN = 6;
0643: /**
0644: * Rounding mode to assert that the requested operation has an exact
0645: * result, hence no rounding is necessary. If this rounding mode is
0646: * specified on an operation that yields an inexact result, an
0647: * <tt>ArithmeticException</tt> is thrown.
0648: */
0649: public final static int ROUND_UNNECESSARY = 7;
0650:
0651: // Scaling/Rounding Operations
0652:
0653: /**
0654: * Returns a BigDecimal whose scale is the specified value, and whose
0655: * unscaled value is determined by multiplying or dividing this
0656: * BigDecimal's unscaled value by the appropriate power of ten to maintain
0657: * its overall value. If the scale is reduced by the operation, the
0658: * unscaled value must be divided (rather than multiplied), and the value
0659: * may be changed; in this case, the specified rounding mode is applied to
0660: * the division.
0661: * <p>
0662: * Note that since BigDecimal objects are immutable, calls of this
0663: * method do <i>not</i> result in the original object being
0664: * modified, contrary to the usual convention of having methods
0665: * named <code>set<i>X</i></code> mutate field
0666: * <code><i>X</i></code>. Instead, <code>setScale</code> returns
0667: * an object with the proper scale; the returned object may or may
0668: * not be newly allocated.
0669: *
0670: * @param scale scale of the BigDecimal value to be returned.
0671: * @param roundingMode The rounding mode to apply.
0672: * @return a BigDecimal whose scale is the specified value, and whose
0673: * unscaled value is determined by multiplying or dividing this
0674: * BigDecimal's unscaled value by the appropriate power of ten to
0675: * maintain its overall value.
0676: * @throws ArithmeticException <tt>scale</tt> is negative, or
0677: * <tt>roundingMode==ROUND_UNNECESSARY</tt> and the specified
0678: * scaling operation would require rounding.
0679: * @throws IllegalArgumentException <tt>roundingMode</tt> does not
0680: * represent a valid rounding mode.
0681: * @see #ROUND_UP
0682: * @see #ROUND_DOWN
0683: * @see #ROUND_CEILING
0684: * @see #ROUND_FLOOR
0685: * @see #ROUND_HALF_UP
0686: * @see #ROUND_HALF_DOWN
0687: * @see #ROUND_HALF_EVEN
0688: * @see #ROUND_UNNECESSARY
0689: */
0690: public BigDecimal setScale(int scale, int roundingMode) {
0691: if (scale < 0)
0692: throw new ArithmeticException("Negative scale");
0693: if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
0694: throw new IllegalArgumentException("Invalid rounding mode");
0695: /* Handle the easy cases */
0696: if (scale == this .scale)
0697: return this ;
0698: else if (scale > this .scale)
0699: return new BigDecimal(timesTenToThe(intVal, scale
0700: - this .scale), scale);
0701: else
0702: /* scale < this.scale */
0703: return divide(valueOf(1), scale, roundingMode);
0704: }
0705:
0706: /**
0707: * Returns a BigDecimal whose scale is the specified value, and whose
0708: * value is numerically equal to this BigDecimal's. Throws an
0709: * ArithmeticException if this is not possible. This call is typically
0710: * used to increase the scale, in which case it is guaranteed that there
0711: * exists a BigDecimal of the specified scale and the correct value. The
0712: * call can also be used to reduce the scale if the caller knows that the
0713: * BigDecimal has sufficiently many zeros at the end of its fractional
0714: * part (i.e., factors of ten in its integer value) to allow for the
0715: * rescaling without loss of precision.
0716: * <p>
0717: * This method returns the same result as the two argument version
0718: * of setScale, but saves the caller the trouble of specifying a
0719: * rounding mode in cases where it is irrelevant.
0720: * <p>
0721: * Note that since BigDecimal objects are immutable, calls of this
0722: * method do <i>not</i> result in the original object being
0723: * modified, contrary to the usual convention of having methods
0724: * named <code>set<i>X</i></code> mutate field
0725: * <code><i>X</i></code>. Instead, <code>setScale</code> returns
0726: * an object with the proper scale; the returned object may or may
0727: * not be newly allocated.
0728: *
0729: * @param scale scale of the BigDecimal value to be returned.
0730: * @return a BigDecimal whose scale is the specified value, and whose
0731: * unscaled value is determined by multiplying or dividing this
0732: * BigDecimal's unscaled value by the appropriate power of ten to
0733: * maintain its overall value.
0734: * @throws ArithmeticException <tt>scale</tt> is negative, or
0735: * the specified scaling operation would require rounding.
0736: * @see #setScale(int, int)
0737: */
0738: public BigDecimal setScale(int scale) {
0739: return setScale(scale, ROUND_UNNECESSARY);
0740: }
0741:
0742: // Decimal Point Motion Operations
0743:
0744: /**
0745: * Returns a BigDecimal which is equivalent to this one with the decimal
0746: * point moved n places to the left. If n is non-negative, the call merely
0747: * adds n to the scale. If n is negative, the call is equivalent to
0748: * movePointRight(-n). (The BigDecimal returned by this call has value
0749: * <tt>(this * 10<sup>-n</sup>)</tt> and scale
0750: * <tt>max(this.scale()+n, 0)</tt>.)
0751: *
0752: * @param n number of places to move the decimal point to the left.
0753: * @return a BigDecimal which is equivalent to this one with the decimal
0754: * point moved <tt>n</tt> places to the left.
0755: */
0756: public BigDecimal movePointLeft(int n) {
0757: return (n >= 0 ? new BigDecimal(intVal, scale + n)
0758: : movePointRight(-n));
0759: }
0760:
0761: /**
0762: * Moves the decimal point the specified number of places to the right.
0763: * If this BigDecimal's scale is >= <tt>n</tt>, the call merely
0764: * subtracts <tt>n</tt> from the scale; otherwise, it sets the scale to
0765: * zero, and multiplies the integer value by
0766: * <tt>10<sup>(n - this.scale)</sup></tt>. If <tt>n</tt>
0767: * is negative, the call is equivalent to <tt>movePointLeft(-n)</tt>. (The
0768: * BigDecimal returned by this call has value
0769: * <tt>(this * 10<sup>n</sup>)</tt> and scale
0770: * <tt>max(this.scale()-n, 0)</tt>.)
0771: *
0772: * @param n number of places to move the decimal point to the right.
0773: * @return a BigDecimal which is equivalent to this one with the decimal
0774: * point moved <tt>n</tt> places to the right.
0775: */
0776: public BigDecimal movePointRight(int n) {
0777: return (scale >= n ? new BigDecimal(intVal, scale - n)
0778: : new BigDecimal(timesTenToThe(intVal, n - scale), 0));
0779: }
0780:
0781: // Comparison Operations
0782:
0783: /**
0784: * Compares this BigDecimal with the specified BigDecimal. Two
0785: * BigDecimals that are equal in value but have a different scale (like
0786: * 2.0 and 2.00) are considered equal by this method. This method is
0787: * provided in preference to individual methods for each of the six
0788: * boolean comparison operators (<, ==, >, >=, !=, <=). The
0789: * suggested idiom for performing these comparisons is:
0790: * <tt>(x.compareTo(y)</tt> <<i>op</i>> <tt>0)</tt>,
0791: * where <<i>op</i>> is one of the six comparison operators.
0792: *
0793: * @param val BigDecimal to which this BigDecimal is to be compared.
0794: * @return -1, 0 or 1 as this BigDecimal is numerically less than, equal
0795: * to, or greater than <tt>val</tt>.
0796: */
0797: public int compareTo(BigDecimal val) {
0798: /* Optimization: would run fine without the next three lines */
0799: int sigDiff = signum() - val.signum();
0800: if (sigDiff != 0)
0801: return (sigDiff > 0 ? 1 : -1);
0802: /* If signs match, scale and compare intVals */
0803: BigDecimal arg[] = new BigDecimal[2];
0804: arg[0] = this ;
0805: arg[1] = val;
0806: matchScale(arg);
0807: return arg[0].intVal.compareTo(arg[1].intVal);
0808: }
0809:
0810: /**
0811: * Compares this BigDecimal with the specified Object. If the Object is a
0812: * BigDecimal, this method behaves like {@link #compareTo compareTo}.
0813: * Otherwise, it throws a <tt>ClassCastException</tt> (as BigDecimals are
0814: * comparable only to other BigDecimals).
0815: *
0816: * @param o Object to which this BigDecimal is to be compared.
0817: * @return a negative number, zero, or a positive number as this
0818: * BigDecimal is numerically less than, equal to, or greater
0819: * than <tt>o</tt>, which must be a BigDecimal.
0820: * @throws ClassCastException <tt>o</tt> is not a BigDecimal.
0821: * @see #compareTo(java.math.BigDecimal)
0822: * @see Comparable
0823: * @since 1.2
0824: */
0825: public int compareTo(Object o) {
0826: return compareTo((BigDecimal) o);
0827: }
0828:
0829: /**
0830: * Compares this BigDecimal with the specified Object for
0831: * equality. Unlike {@link #compareTo compareTo}, this method
0832: * considers two BigDecimals equal only if they are equal in value
0833: * and scale (thus 2.0 is not equal to 2.00 when compared by this
0834: * method).
0835: *
0836: * @param x Object to which this BigDecimal is to be compared.
0837: * @return <tt>true</tt> if and only if the specified Object is a
0838: * BigDecimal whose value and scale are equal to this BigDecimal's.
0839: * @see #compareTo(java.math.BigDecimal)
0840: */
0841: public boolean equals(Object x) {
0842: if (!(x instanceof BigDecimal))
0843: return false;
0844: BigDecimal xDec = (BigDecimal) x;
0845: return scale == xDec.scale && intVal.equals(xDec.intVal);
0846: }
0847:
0848: /**
0849: * Returns the minimum of this BigDecimal and <tt>val</tt>.
0850: *
0851: * @param val value with which the minimum is to be computed.
0852: * @return the BigDecimal whose value is the lesser of this BigDecimal and
0853: * <tt>val</tt>. If they are equal, as defined by the
0854: * {@link #compareTo compareTo} method, either may be returned.
0855: * @see #compareTo(java.math.BigDecimal)
0856: */
0857: public BigDecimal min(BigDecimal val) {
0858: return (compareTo(val) < 0 ? this : val);
0859: }
0860:
0861: /**
0862: * Returns the maximum of this BigDecimal and <tt>val</tt>.
0863: *
0864: * @param val value with which the maximum is to be computed.
0865: * @return the BigDecimal whose value is the greater of this BigDecimal
0866: * and <tt>val</tt>. If they are equal, as defined by the
0867: * {@link #compareTo compareTo} method, either may be returned.
0868: * @see #compareTo(java.math.BigDecimal)
0869: */
0870: public BigDecimal max(BigDecimal val) {
0871: return (compareTo(val) > 0 ? this : val);
0872: }
0873:
0874: // Hash Function
0875:
0876: /**
0877: * Returns the hash code for this BigDecimal. Note that two BigDecimals
0878: * that are numerically equal but differ in scale (like 2.0 and 2.00)
0879: * will generally <i>not</i> have the same hash code.
0880: *
0881: * @return hash code for this BigDecimal.
0882: */
0883: public int hashCode() {
0884: return 31 * intVal.hashCode() + scale;
0885: }
0886:
0887: //
0888: // add one to the least significant digit.
0889: // in the unlikely event there is a carry out,
0890: // deal with it.
0891: //
0892: private String roundup(String val) {
0893: int i;
0894: char[] digits = val.toCharArray();
0895: int nDigits = digits.length;
0896:
0897: int q = digits[i = (nDigits - 1)];
0898: if (q == '9') {
0899: while (q == '9' && i > 0) {
0900: digits[i] = '0';
0901: q = digits[--i];
0902: }
0903: if (q == '9') {
0904: // carryout! High-order 1, rest 0s, larger exp.
0905: digits[0] = '0';
0906: return "1" + String.valueOf(digits);
0907: }
0908: // else fall through.
0909: }
0910: digits[i] = (char) (q + 1);
0911: return String.valueOf(digits);
0912: }
0913:
0914: // Format Converters
0915:
0916: /**
0917: * Returns the string representation of this BigDecimal. The digit-to-
0918: * character mapping provided by {@link Character#forDigit} is used.
0919: * A leading minus sign is used to indicate sign, and the number of digits
0920: * to the right of the decimal point is used to indicate scale. (This
0921: * representation is compatible with the (String) constructor.)
0922: *
0923: * @return String representation of this BigDecimal.
0924: * @see Character#forDigit
0925: * @see #BigDecimal(java.lang.String)
0926: */
0927: public String toString() {
0928: if (scale == 0) /* No decimal point */
0929: return intVal.toString();
0930: return getValueString(signum(), intVal.abs().toString(), scale);
0931: }
0932:
0933: /**
0934: * Converts this BigDecimal to a BigInteger. This conversion is
0935: * analogous to a <a
0936: * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
0937: * primitive conversion</i></a> from <code>double</code> to
0938: * <code>long</code> as defined in the <a
0939: * href="http://java.sun.com/docs/books/jls/html/">Java Language
0940: * Specification</a>: any fractional part of this BigDecimal will
0941: * be discarded. Note that this conversion can lose information
0942: * about the precision of the BigDecimal value.
0943: *
0944: * @return this BigDecimal converted to a BigInteger.
0945: */
0946: public BigInteger toBigInteger() {
0947: return (scale == 0 ? intVal : intVal.divide(BigInteger.valueOf(
0948: 10).pow(scale)));
0949: }
0950:
0951: /**
0952: * Converts this BigDecimal to an <code>int</code>. This
0953: * conversion is analogous to a <a
0954: * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
0955: * primitive conversion</i></a> from <code>double</code> to
0956: * <code>short</code> as defined in the <a
0957: * href="http://java.sun.com/docs/books/jls/html/">Java Language
0958: * Specification</a>: any fractional part of this BigDecimal will
0959: * be discarded, and if the resulting "BigInteger" is
0960: * too big to fit in an <code>int</code>, only the low-order 32
0961: * bits are returned. Note that this conversion can lose
0962: * information about the overall magnitude and precision of the
0963: * BigDecimal value as well as return a result with the opposite
0964: * sign.
0965: *
0966: * @return this BigDecimal converted to an <code>int</code>.
0967: */
0968: public int intValue() {
0969: return toBigInteger().intValue();
0970: }
0971:
0972: /**
0973: * Converts this BigDecimal to a <code>long</code>. This
0974: * conversion is analogous to a <a
0975: * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
0976: * primitive conversion</i></a> from <code>double</code> to
0977: * <code>short</code> as defined in the <a
0978: * href="http://java.sun.com/docs/books/jls/html/">Java Language
0979: * Specification</a>: any fractional part of this BigDecimal will
0980: * be discarded, and if the resulting "BigInteger" is
0981: * too big to fit in a <code>long</code>, only the low-order 64
0982: * bits are returned. Note that this conversion can lose
0983: * information about the overall magnitude and precision of the
0984: * BigDecimal value as well as return a result with the opposite
0985: * sign.
0986: *
0987: * @return this BigDecimal converted to an <code>long</code>.
0988: */
0989: public long longValue() {
0990: return toBigInteger().longValue();
0991: }
0992:
0993: /**
0994: * Converts this BigDecimal to a <code>float</code>. This
0995: * conversion is similar to the <a
0996: * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
0997: * primitive conversion</i></a> from <code>double</code> to
0998: * <code>float</code> defined in the <a
0999: * href="http://java.sun.com/docs/books/jls/html/">Java Language
1000: * Specification</a>: if this BigDecimal has too great a magnitude
1001: * to represent as a <code>float</code>, it will be converted to
1002: * {@link Float#NEGATIVE_INFINITY} or {@link
1003: * Float#POSITIVE_INFINITY} as appropriate. Note that even when
1004: * the return value is finite, this conversion can lose
1005: * information about the precision of the BigDecimal value.
1006: *
1007: * @return this BigDecimal converted to a <code>float</code>.
1008: */
1009: public float floatValue() {
1010: /* Somewhat inefficient, but guaranteed to work. */
1011: return Float.valueOf(this .toString()).floatValue();
1012: }
1013:
1014: /**
1015: * Converts this BigDecimal to a <code>double</code>. This
1016: * conversion is similar to the <a
1017: * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
1018: * primitive conversion</i></a> from <code>double</code> to
1019: * <code>float</code> as defined in the <a
1020: * href="http://java.sun.com/docs/books/jls/html/">Java Language
1021: * Specification</a>: if this BigDecimal has too great a magnitude
1022: * represent as a <code>double</code>, it will be converted to
1023: * {@link Double#NEGATIVE_INFINITY} or {@link
1024: * Double#POSITIVE_INFINITY} as appropriate. Note that even when
1025: * the return value is finite, this conversion can lose
1026: * information about the precision of the BigDecimal value.
1027: *
1028: * @return this BigDecimal converted to a <code>double</code>.
1029: */
1030: public double doubleValue() {
1031: /* Somewhat inefficient, but guaranteed to work. */
1032: return Double.valueOf(this .toString()).doubleValue();
1033: }
1034:
1035: // Private "Helper" Methods
1036:
1037: /* Returns a digit.digit string */
1038: private String getValueString(int signum, String intString,
1039: int scale) {
1040: /* Insert decimal point */
1041: StringBuffer buf;
1042: int insertionPoint = intString.length() - scale;
1043: if (insertionPoint == 0) { /* Point goes right before intVal */
1044: return (signum < 0 ? "-0." : "0.") + intString;
1045: } else if (insertionPoint > 0) { /* Point goes inside intVal */
1046: buf = new StringBuffer(intString);
1047: buf.insert(insertionPoint, '.');
1048: if (signum < 0)
1049: buf.insert(0, '-');
1050: } else { /* We must insert zeros between point and intVal */
1051: buf = new StringBuffer(3 - insertionPoint
1052: + intString.length());
1053: buf.append(signum < 0 ? "-0." : "0.");
1054: for (int i = 0; i < -insertionPoint; i++)
1055: buf.append('0');
1056: buf.append(intString);
1057: }
1058: return buf.toString();
1059: }
1060:
1061: /* Returns (a * 10^b) */
1062: private static BigInteger timesTenToThe(BigInteger a, int b) {
1063: return a.multiply(BigInteger.valueOf(10).pow(b));
1064: }
1065:
1066: /*
1067: * If the scales of val[0] and val[1] differ, rescale (non-destructively)
1068: * the lower-scaled BigDecimal so they match.
1069: */
1070: private static void matchScale(BigDecimal[] val) {
1071: if (val[0].scale < val[1].scale)
1072: val[0] = val[0].setScale(val[1].scale);
1073: else if (val[1].scale < val[0].scale)
1074: val[1] = val[1].setScale(val[0].scale);
1075: }
1076:
1077: /**
1078: * Reconstitute the <tt>BigDecimal</tt> instance from a stream (that is,
1079: * deserialize it).
1080: */
1081: private synchronized void readObject(java.io.ObjectInputStream s)
1082: throws java.io.IOException, ClassNotFoundException {
1083: // Read in all fields
1084: s.defaultReadObject();
1085: // Validate scale factor
1086: if (scale < 0)
1087: throw new java.io.StreamCorruptedException(
1088: "BigDecimal: Negative scale");
1089: }
1090: }
|