0001: //##header
0002: /* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
0003: /* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
0004: package com.ibm.icu.math;
0005:
0006: import java.math.BigInteger;
0007: import com.ibm.icu.impl.Utility;
0008:
0009: /* ------------------------------------------------------------------ */
0010: /* BigDecimal -- Decimal arithmetic for Java */
0011: /* ------------------------------------------------------------------ */
0012: /* Copyright IBM Corporation, 1996-2006. All Rights Reserved. */
0013: /* */
0014: /* The BigDecimal class provides immutable arbitrary-precision */
0015: /* floating point (including integer) decimal numbers. */
0016: /* */
0017: /* As the numbers are decimal, there is an exact correspondence */
0018: /* between an instance of a BigDecimal object and its String */
0019: /* representation; the BigDecimal class provides direct conversions */
0020: /* to and from String and character array objects, and well as */
0021: /* conversions to and from the Java primitive types (which may not */
0022: /* be exact). */
0023: /* ------------------------------------------------------------------ */
0024: /* Notes: */
0025: /* */
0026: /* 1. A BigDecimal object is never changed in value once constructed; */
0027: /* this avoids the need for locking. Note in particular that the */
0028: /* mantissa array may be shared between many BigDecimal objects, */
0029: /* so that once exposed it must not be altered. */
0030: /* */
0031: /* 2. This class looks at MathContext class fields directly (for */
0032: /* performance). It must not and does not change them. */
0033: /* */
0034: /* 3. Exponent checking is delayed until finish(), as we know */
0035: /* intermediate calculations cannot cause 31-bit overflow. */
0036: /* [This assertion depends on MAX_DIGITS in MathContext.] */
0037: /* */
0038: /* 4. Comments for the public API now follow the javadoc conventions. */
0039: /* The NetRexx -comments option is used to pass these comments */
0040: /* through to the generated Java code (with -format, if desired). */
0041: /* */
0042: /* 5. System.arraycopy is faster than explicit loop as follows */
0043: /* Mean length 4: equal */
0044: /* Mean length 8: x2 */
0045: /* Mean length 16: x3 */
0046: /* Mean length 24: x4 */
0047: /* From prior experience, we expect mean length a little below 8, */
0048: /* but arraycopy is still the one to use, in general, until later */
0049: /* measurements suggest otherwise. */
0050: /* */
0051: /* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */
0052: /* assembler code implementation of the algorithms below; it is */
0053: /* now called IXXRCN and is available with the OS/390 and VM/ESA */
0054: /* operating systems. */
0055: /* ------------------------------------------------------------------ */
0056: /* Change History: */
0057: /* 1997.09.02 Initial version (derived from netrexx.lang classes) */
0058: /* 1997.09.12 Add lostDigits checking */
0059: /* 1997.10.06 Change mantissa to a byte array */
0060: /* 1997.11.22 Rework power [did not prepare arguments, etc.] */
0061: /* 1997.12.13 multiply did not prepare arguments */
0062: /* 1997.12.14 add did not prepare and align arguments correctly */
0063: /* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */
0064: /* 1998.05.21 adjust remainder operator finalization */
0065: /* 1998.06.04 rework to pass MathContext to finish() and round() */
0066: /* 1998.06.06 change format to use round(); support rounding modes */
0067: /* 1998.06.25 rename to BigDecimal and begin merge */
0068: /* zero can now have trailing zeros (i.e., exp\=0) */
0069: /* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */
0070: /* unscaledValue, valueof */
0071: /* 1998.07.01 improve byteaddsub to allow array reuse, etc. */
0072: /* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */
0073: /* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */
0074: /* 1998.07.08 setScale, faster equals */
0075: /* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
0076: /* 1998.10.12 change package to com.ibm.icu.math */
0077: /* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */
0078: /* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
0079: /* 1998.12.29 improve byteaddsub by using table lookup */
0080: /* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
0081: /* 1999.02.05 cleaner code for BigDecimal(char[]) */
0082: /* 1999.02.06 add javadoc comments */
0083: /* 1999.02.11 format() changed from 7 to 2 method form */
0084: /* 1999.03.05 null pointer checking is no longer explicit */
0085: /* 1999.03.05 simplify; changes from discussion with J. Bloch: */
0086: /* null no longer permitted for MathContext; drop boolean, */
0087: /* byte, char, float, short constructor, deprecate double */
0088: /* constructor, no blanks in string constructor, add */
0089: /* offset and length version of char[] constructor; */
0090: /* add valueOf(double); drop booleanValue, charValue; */
0091: /* add ...Exact versions of remaining convertors */
0092: /* 1999.03.13 add toBigIntegerExact */
0093: /* 1999.03.13 1.00 release to IBM Centre for Java Technology */
0094: /* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */
0095: /* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */
0096: /* 1999.07.03 1.03 lost digits should not be checked if digits=0 */
0097: /* 1999.07.06 lost digits Exception message changed */
0098: /* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */
0099: /* 1999.07.17 improve messages from pow method */
0100: /* 1999.08.08 performance tweaks */
0101: /* 1999.08.15 fastpath in multiply */
0102: /* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */
0103: /* 1999.12.22 1.06 remove multiply fastpath, and improve performance */
0104: /* 2000.01.01 copyright update [Y2K has arrived] */
0105: /* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */
0106: /* ------------------------------------------------------------------ */
0107:
0108: /**
0109: * The <code>BigDecimal</code> class implements immutable
0110: * arbitrary-precision decimal numbers. The methods of the
0111: * <code>BigDecimal</code> class provide operations for fixed and
0112: * floating point arithmetic, comparison, format conversions, and
0113: * hashing.
0114: * <p>
0115: * As the numbers are decimal, there is an exact correspondence between
0116: * an instance of a <code>BigDecimal</code> object and its
0117: * <code>String</code> representation; the <code>BigDecimal</code> class
0118: * provides direct conversions to and from <code>String</code> and
0119: * character array (<code>char[]</code>) objects, as well as conversions
0120: * to and from the Java primitive types (which may not be exact) and
0121: * <code>BigInteger</code>.
0122: * <p>
0123: * In the descriptions of constructors and methods in this documentation,
0124: * the value of a <code>BigDecimal</code> number object is shown as the
0125: * result of invoking the <code>toString()</code> method on the object.
0126: * The internal representation of a decimal number is neither defined
0127: * nor exposed, and is not permitted to affect the result of any
0128: * operation.
0129: * <p>
0130: * The floating point arithmetic provided by this class is defined by
0131: * the ANSI X3.274-1996 standard, and is also documented at
0132: * <code>http://www2.hursley.ibm.com/decimal</code>
0133: * <br><i>[This URL will change.]</i>
0134: *
0135: * <h3>Operator methods</h3>
0136: * <p>
0137: * Operations on <code>BigDecimal</code> numbers are controlled by a
0138: * {@link MathContext} object, which provides the context (precision and
0139: * other information) for the operation. Methods that can take a
0140: * <code>MathContext</code> parameter implement the standard arithmetic
0141: * operators for <code>BigDecimal</code> objects and are known as
0142: * <i>operator methods</i>. The default settings provided by the
0143: * constant {@link MathContext#DEFAULT} (<code>digits=9,
0144: * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>)
0145: * perform general-purpose floating point arithmetic to nine digits of
0146: * precision. The <code>MathContext</code> parameter must not be
0147: * <code>null</code>.
0148: * <p>
0149: * Each operator method also has a version provided which does
0150: * not take a <code>MathContext</code> parameter. For this version of
0151: * each method, the context settings used are <code>digits=0,
0152: * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>;
0153: * these settings perform fixed point arithmetic with unlimited
0154: * precision, as defined for the original BigDecimal class in Java 1.1
0155: * and Java 1.2.
0156: * <p>
0157: * For monadic operators, only the optional <code>MathContext</code>
0158: * parameter is present; the operation acts upon the current object.
0159: * <p>
0160: * For dyadic operators, a <code>BigDecimal</code> parameter is always
0161: * present; it must not be <code>null</code>.
0162: * The operation acts with the current object being the left-hand operand
0163: * and the <code>BigDecimal</code> parameter being the right-hand operand.
0164: * <p>
0165: * For example, adding two <code>BigDecimal</code> objects referred to
0166: * by the names <code>award</code> and <code>extra</code> could be
0167: * written as any of:
0168: * <p><code>
0169: * award.add(extra)
0170: * <br>award.add(extra, MathContext.DEFAULT)
0171: * <br>award.add(extra, acontext)
0172: * </code>
0173: * <p>
0174: * (where <code>acontext</code> is a <code>MathContext</code> object),
0175: * which would return a <code>BigDecimal</code> object whose value is
0176: * the result of adding <code>award</code> and <code>extra</code> under
0177: * the appropriate context settings.
0178: * <p>
0179: * When a <code>BigDecimal</code> operator method is used, a set of
0180: * rules define what the result will be (and, by implication, how the
0181: * result would be represented as a character string).
0182: * These rules are defined in the BigDecimal arithmetic documentation
0183: * (see the URL above), but in summary:
0184: * <ul>
0185: * <li>Results are normally calculated with up to some maximum number of
0186: * significant digits.
0187: * For example, if the <code>MathContext</code> parameter for an operation
0188: * were <code>MathContext.DEFAULT</code> then the result would be
0189: * rounded to 9 digits; the division of 2 by 3 would then result in
0190: * 0.666666667.
0191: * <br>
0192: * You can change the default of 9 significant digits by providing the
0193: * method with a suitable <code>MathContext</code> object. This lets you
0194: * calculate using as many digits as you need -- thousands, if necessary.
0195: * Fixed point (scaled) arithmetic is indicated by using a
0196: * <code>digits</code> setting of 0 (or omitting the
0197: * <code>MathContext</code> parameter).
0198: * <br>
0199: * Similarly, you can change the algorithm used for rounding from the
0200: * default "classic" algorithm.
0201: * <li>
0202: * In standard arithmetic (that is, when the <code>form</code> setting
0203: * is not <code>PLAIN</code>), a zero result is always expressed as the
0204: * single digit <code>'0'</code> (that is, with no sign, decimal point,
0205: * or exponent part).
0206: * <li>
0207: * Except for the division and power operators in standard arithmetic,
0208: * trailing zeros are preserved (this is in contrast to binary floating
0209: * point operations and most electronic calculators, which lose the
0210: * information about trailing zeros in the fractional part of results).
0211: * <br>
0212: * So, for example:
0213: * <p><code>
0214: * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40"
0215: * <br>new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40"
0216: * <br>new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80"
0217: * <br>new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2"
0218: * </code>
0219: * <p>where the value on the right of the <code>=></code> would be the
0220: * result of the operation, expressed as a <code>String</code>, and
0221: * <code>def</code> (in this and following examples) refers to
0222: * <code>MathContext.DEFAULT</code>).
0223: * This preservation of trailing zeros is desirable for most
0224: * calculations (including financial calculations).
0225: * If necessary, trailing zeros may be easily removed using division by 1.
0226: * <li>
0227: * In standard arithmetic, exponential form is used for a result
0228: * depending on its value and the current setting of <code>digits</code>
0229: * (the default is 9 digits).
0230: * If the number of places needed before the decimal point exceeds the
0231: * <code>digits</code> setting, or the absolute value of the number is
0232: * less than <code>0.000001</code>, then the number will be expressed in
0233: * exponential notation; thus
0234: * <p><code>
0235: * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
0236: * </code>
0237: * <p>results in <code>1E+12</code> instead of
0238: * <code>1000000000000</code>, and
0239: * <p><code>
0240: * new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
0241: * </code>
0242: * <p>results in <code>3.33333333E-11</code> instead of
0243: * <code>0.0000000000333333333</code>.
0244: * <p>
0245: * The form of the exponential notation (scientific or engineering) is
0246: * determined by the <code>form</code> setting.
0247: * <eul>
0248: * <p>
0249: * The names of methods in this class follow the conventions established
0250: * by <code>java.lang.Number</code>, <code>java.math.BigInteger</code>,
0251: * and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
0252: *
0253: * @see MathContext
0254: * @author Mike Cowlishaw
0255: * @stable ICU 2.0
0256: */
0257:
0258: public class BigDecimal extends java.lang.Number implements
0259: java.io.Serializable, java.lang.Comparable {
0260: private static final java.lang.String $0 = "BigDecimal.nrx";
0261:
0262: /* ----- Constants ----- */
0263: /* properties constant public */// useful to others
0264: /**
0265: * The <code>BigDecimal</code> constant "0".
0266: *
0267: * @see #ONE
0268: * @see #TEN
0269: * @stable ICU 2.0
0270: */
0271: public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal(
0272: (long) 0); // use long as we want the int constructor
0273: // .. to be able to use this, for speed
0274:
0275: /**
0276: * The <code>BigDecimal</code> constant "1".
0277: *
0278: * @see #TEN
0279: * @see #ZERO
0280: * @stable ICU 2.0
0281: */
0282: public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal(
0283: (long) 1); // use long as we want the int constructor
0284: // .. to be able to use this, for speed
0285:
0286: /**
0287: * The <code>BigDecimal</code> constant "10".
0288: *
0289: * @see #ONE
0290: * @see #ZERO
0291: * @stable ICU 2.0
0292: */
0293: public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(
0294: 10);
0295:
0296: // the rounding modes (copied here for upwards compatibility)
0297: /**
0298: * Rounding mode to round to a more positive number.
0299: * @see MathContext#ROUND_CEILING
0300: * @stable ICU 2.0
0301: */
0302: public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING;
0303:
0304: /**
0305: * Rounding mode to round towards zero.
0306: * @see MathContext#ROUND_DOWN
0307: * @stable ICU 2.0
0308: */
0309: public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN;
0310:
0311: /**
0312: * Rounding mode to round to a more negative number.
0313: * @see MathContext#ROUND_FLOOR
0314: * @stable ICU 2.0
0315: */
0316: public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR;
0317:
0318: /**
0319: * Rounding mode to round to nearest neighbor, where an equidistant
0320: * value is rounded down.
0321: * @see MathContext#ROUND_HALF_DOWN
0322: * @stable ICU 2.0
0323: */
0324: public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;
0325:
0326: /**
0327: * Rounding mode to round to nearest neighbor, where an equidistant
0328: * value is rounded to the nearest even neighbor.
0329: * @see MathContext#ROUND_HALF_EVEN
0330: * @stable ICU 2.0
0331: */
0332: public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;
0333:
0334: /**
0335: * Rounding mode to round to nearest neighbor, where an equidistant
0336: * value is rounded up.
0337: * @see MathContext#ROUND_HALF_UP
0338: * @stable ICU 2.0
0339: */
0340: public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP;
0341:
0342: /**
0343: * Rounding mode to assert that no rounding is necessary.
0344: * @see MathContext#ROUND_UNNECESSARY
0345: * @stable ICU 2.0
0346: */
0347: public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;
0348:
0349: /**
0350: * Rounding mode to round away from zero.
0351: * @see MathContext#ROUND_UP
0352: * @stable ICU 2.0
0353: */
0354: public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP;
0355:
0356: /* properties constant private */// locals
0357: private static final byte ispos = 1; // ind: indicates positive (must be 1)
0358: private static final byte iszero = 0; // ind: indicates zero (must be 0)
0359: private static final byte isneg = -1; // ind: indicates negative (must be -1)
0360: // [later could add NaN, +/- infinity, here]
0361:
0362: private static final int MinExp = -999999999; // minimum exponent allowed
0363: private static final int MaxExp = 999999999; // maximum exponent allowed
0364: private static final int MinArg = -999999999; // minimum argument integer
0365: private static final int MaxArg = 999999999; // maximum argument integer
0366:
0367: private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(
0368: 0, com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math
0369:
0370: /* properties constant private unused */// present but not referenced
0371: // Serialization version
0372: private static final long serialVersionUID = 8245355804974198832L;
0373:
0374: private static final java.lang.String copyright = " Copyright (c) IBM Corporation 1996, 2000. All rights reserved. ";
0375:
0376: /* properties static private */
0377: // Precalculated constant arrays (used by byteaddsub)
0378: private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
0379: private static byte bytedig[] = diginit(); // next digit array
0380:
0381: /* ----- Instance properties [all private and immutable] ----- */
0382: /* properties private */
0383:
0384: /**
0385: * The indicator. This may take the values:
0386: * <ul>
0387: * <li>ispos -- the number is positive
0388: * <li>iszero -- the number is zero
0389: * <li>isneg -- the number is negative
0390: * </ul>
0391: *
0392: * @serial
0393: */
0394: private byte ind; // assumed undefined
0395: // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
0396: // We only need two bits for this, but use a byte [also permits
0397: // smooth future extension].
0398:
0399: /**
0400: * The formatting style. This may take the values:
0401: * <ul>
0402: * <li>MathContext.PLAIN -- no exponent needed
0403: * <li>MathContext.SCIENTIFIC -- scientific notation required
0404: * <li>MathContext.ENGINEERING -- engineering notation required
0405: * </ul>
0406: * <p>
0407: * This property is an optimization; it allows us to defer number
0408: * layout until it is actually needed as a string, hence avoiding
0409: * unnecessary formatting.
0410: *
0411: * @serial
0412: */
0413: private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
0414: // We only need two bits for this, at present, but use a byte
0415: // [again, to allow for smooth future extension]
0416:
0417: /**
0418: * The value of the mantissa.
0419: * <p>
0420: * Once constructed, this may become shared between several BigDecimal
0421: * objects, so must not be altered.
0422: * <p>
0423: * For efficiency (speed), this is a byte array, with each byte
0424: * taking a value of 0 -> 9.
0425: * <p>
0426: * If the first byte is 0 then the value of the number is zero (and
0427: * mant.length=1, except when constructed from a plain number, for
0428: * example, 0.000).
0429: *
0430: * @serial
0431: */
0432: private byte mant[]; // assumed null
0433:
0434: /**
0435: * The exponent.
0436: * <p>
0437: * For fixed point arithmetic, scale is <code>-exp</code>, and can
0438: * apply to zero.
0439: *
0440: * Note that this property can have a value less than MinExp when
0441: * the mantissa has more than one digit.
0442: *
0443: * @serial
0444: */
0445: private int exp;
0446:
0447: // assumed 0
0448:
0449: /* ---------------------------------------------------------------- */
0450: /* Constructors */
0451: /* ---------------------------------------------------------------- */
0452:
0453: //#ifndef FOUNDATION
0454: /**
0455: * Constructs a <code>BigDecimal</code> object from a
0456: * <code>java.math.BigDecimal</code>.
0457: * <p>
0458: * Constructs a <code>BigDecimal</code> as though the parameter had
0459: * been represented as a <code>String</code> (using its
0460: * <code>toString</code> method) and the
0461: * {@link #BigDecimal(java.lang.String)} constructor had then been
0462: * used.
0463: * The parameter must not be <code>null</code>.
0464: * <p>
0465: * <i>(Note: this constructor is provided only in the
0466: * <code>com.ibm.icu.math</code> version of the BigDecimal class.
0467: * It would not be present in a <code>java.math</code> version.)</i>
0468: *
0469: * @param bd The <code>BigDecimal</code> to be translated.
0470: * @stable ICU 2.0
0471: */
0472:
0473: public BigDecimal(java.math.BigDecimal bd) {
0474: this (bd.toString());
0475: return;
0476: }
0477:
0478: //#endif
0479:
0480: /**
0481: * Constructs a <code>BigDecimal</code> object from a
0482: * <code>BigInteger</code>, with scale 0.
0483: * <p>
0484: * Constructs a <code>BigDecimal</code> which is the exact decimal
0485: * representation of the <code>BigInteger</code>, with a scale of
0486: * zero.
0487: * The value of the <code>BigDecimal</code> is identical to the value
0488: * of the <code>BigInteger</code>.
0489: * The parameter must not be <code>null</code>.
0490: * <p>
0491: * The <code>BigDecimal</code> will contain only decimal digits,
0492: * prefixed with a leading minus sign (hyphen) if the
0493: * <code>BigInteger</code> is negative. A leading zero will be
0494: * present only if the <code>BigInteger</code> is zero.
0495: *
0496: * @param bi The <code>BigInteger</code> to be converted.
0497: * @stable ICU 2.0
0498: */
0499:
0500: public BigDecimal(java.math.BigInteger bi) {
0501: this (bi.toString(10));
0502: return;
0503: }
0504:
0505: // exp remains 0
0506:
0507: /**
0508: * Constructs a <code>BigDecimal</code> object from a
0509: * <code>BigInteger</code> and a scale.
0510: * <p>
0511: * Constructs a <code>BigDecimal</code> which is the exact decimal
0512: * representation of the <code>BigInteger</code>, scaled by the
0513: * second parameter, which may not be negative.
0514: * The value of the <code>BigDecimal</code> is the
0515: * <code>BigInteger</code> divided by ten to the power of the scale.
0516: * The <code>BigInteger</code> parameter must not be
0517: * <code>null</code>.
0518: * <p>
0519: * The <code>BigDecimal</code> will contain only decimal digits, (with
0520: * an embedded decimal point followed by <code>scale</code> decimal
0521: * digits if the scale is positive), prefixed with a leading minus
0522: * sign (hyphen) if the <code>BigInteger</code> is negative. A
0523: * leading zero will be present only if the <code>BigInteger</code> is
0524: * zero.
0525: *
0526: * @param bi The <code>BigInteger</code> to be converted.
0527: * @param scale The <code>int</code> specifying the scale.
0528: * @throws NumberFormatException if the scale is negative.
0529: * @stable ICU 2.0
0530: */
0531:
0532: public BigDecimal(java.math.BigInteger bi, int scale) {
0533: this (bi.toString(10));
0534: if (scale < 0)
0535: throw new java.lang.NumberFormatException("Negative scale:"
0536: + " " + scale);
0537: exp = (int) -scale; // exponent is -scale
0538: return;
0539: }
0540:
0541: /**
0542: * Constructs a <code>BigDecimal</code> object from an array of characters.
0543: * <p>
0544: * Constructs a <code>BigDecimal</code> as though a
0545: * <code>String</code> had been constructed from the character array
0546: * and the {@link #BigDecimal(java.lang.String)} constructor had then
0547: * been used. The parameter must not be <code>null</code>.
0548: * <p>
0549: * Using this constructor is faster than using the
0550: * <code>BigDecimal(String)</code> constructor if the string is
0551: * already available in character array form.
0552: *
0553: * @param inchars The <code>char[]</code> array containing the number
0554: * to be converted.
0555: * @throws NumberFormatException if the parameter is not a valid
0556: * number.
0557: * @stable ICU 2.0
0558: */
0559:
0560: public BigDecimal(char inchars[]) {
0561: this (inchars, 0, inchars.length);
0562: return;
0563: }
0564:
0565: /**
0566: * Constructs a <code>BigDecimal</code> object from an array of characters.
0567: * <p>
0568: * Constructs a <code>BigDecimal</code> as though a
0569: * <code>String</code> had been constructed from the character array
0570: * (or a subarray of that array) and the
0571: * {@link #BigDecimal(java.lang.String)} constructor had then been
0572: * used. The first parameter must not be <code>null</code>, and the
0573: * subarray must be wholly contained within it.
0574: * <p>
0575: * Using this constructor is faster than using the
0576: * <code>BigDecimal(String)</code> constructor if the string is
0577: * already available within a character array.
0578: *
0579: * @param inchars The <code>char[]</code> array containing the number
0580: * to be converted.
0581: * @param offset The <code>int</code> offset into the array of the
0582: * start of the number to be converted.
0583: * @param length The <code>int</code> length of the number.
0584: * @throws NumberFormatException if the parameter is not a valid
0585: * number for any reason.
0586: * @stable ICU 2.0
0587: */
0588:
0589: public BigDecimal(char inchars[], int offset, int length) {
0590: super ();
0591: boolean exotic;
0592: boolean hadexp;
0593: int d;
0594: int dotoff;
0595: int last;
0596: int i = 0;
0597: char si = 0;
0598: boolean eneg = false;
0599: int k = 0;
0600: int elen = 0;
0601: int j = 0;
0602: char sj = 0;
0603: int dvalue = 0;
0604: int mag = 0;
0605: // This is the primary constructor; all incoming strings end up
0606: // here; it uses explicit (inline) parsing for speed and to avoid
0607: // generating intermediate (temporary) objects of any kind.
0608: // 1998.06.25: exponent form built only if E/e in string
0609: // 1998.06.25: trailing zeros not removed for zero
0610: // 1999.03.06: no embedded blanks; allow offset and length
0611: if (length <= 0)
0612: bad(inchars); // bad conversion (empty string)
0613: // [bad offset will raise array bounds exception]
0614:
0615: /* Handle and step past sign */
0616: ind = ispos; // assume positive
0617: if (inchars[offset] == ('-')) {
0618: length--;
0619: if (length == 0)
0620: bad(inchars); // nothing after sign
0621: ind = isneg;
0622: offset++;
0623: } else if (inchars[offset] == ('+')) {
0624: length--;
0625: if (length == 0)
0626: bad(inchars); // nothing after sign
0627: offset++;
0628: }
0629:
0630: /* We're at the start of the number */
0631: exotic = false; // have extra digits
0632: hadexp = false; // had explicit exponent
0633: d = 0; // count of digits found
0634: dotoff = -1; // offset where dot was found
0635: last = -1; // last character of mantissa
0636: {
0637: int $1 = length;
0638: i = offset;
0639: i: for (; $1 > 0; $1--, i++) {
0640: si = inchars[i];
0641: if (si >= '0') // test for Arabic digit
0642: if (si <= '9') {
0643: last = i;
0644: d++; // still in mantissa
0645: continue i;
0646: }
0647: if (si == '.') { // record and ignore
0648: if (dotoff >= 0)
0649: bad(inchars); // two dots
0650: dotoff = i - offset; // offset into mantissa
0651: continue i;
0652: }
0653: if (si != 'e')
0654: if (si != 'E') { // expect an extra digit
0655: if ((!(java.lang.Character.isDigit(si))))
0656: bad(inchars); // not a number
0657: // defer the base 10 check until later to avoid extra method call
0658: exotic = true; // will need conversion later
0659: last = i;
0660: d++; // still in mantissa
0661: continue i;
0662: }
0663: /* Found 'e' or 'E' -- now process explicit exponent */
0664: // 1998.07.11: sign no longer required
0665: if ((i - offset) > (length - 2))
0666: bad(inchars); // no room for even one digit
0667: eneg = false;
0668: if ((inchars[i + 1]) == ('-')) {
0669: eneg = true;
0670: k = i + 2;
0671: } else if ((inchars[i + 1]) == ('+'))
0672: k = i + 2;
0673: else
0674: k = i + 1;
0675: // k is offset of first expected digit
0676: elen = length - ((k - offset)); // possible number of digits
0677: if ((elen == 0) | (elen > 9))
0678: bad(inchars); // 0 or more than 9 digits
0679: {
0680: int $2 = elen;
0681: j = k;
0682: j: for (; $2 > 0; $2--, j++) {
0683: sj = inchars[j];
0684: if (sj < '0')
0685: bad(inchars); // always bad
0686: if (sj > '9') { // maybe an exotic digit
0687: if ((!(java.lang.Character.isDigit(sj))))
0688: bad(inchars); // not a number
0689: dvalue = java.lang.Character.digit(sj, 10); // check base
0690: if (dvalue < 0)
0691: bad(inchars); // not base 10
0692: } else
0693: dvalue = ((int) (sj)) - ((int) ('0'));
0694: exp = (exp * 10) + dvalue;
0695: }
0696: }/*j*/
0697: if (eneg)
0698: exp = (int) -exp; // was negative
0699: hadexp = true; // remember we had one
0700: break i; // we are done
0701: }
0702: }/*i*/
0703:
0704: /* Here when all inspected */
0705: if (d == 0)
0706: bad(inchars); // no mantissa digits
0707: if (dotoff >= 0)
0708: exp = (exp + dotoff) - d; // adjust exponent if had dot
0709:
0710: /* strip leading zeros/dot (leave final if all 0's) */
0711: {
0712: int $3 = last - 1;
0713: i = offset;
0714: i: for (; i <= $3; i++) {
0715: si = inchars[i];
0716: if (si == '0') {
0717: offset++;
0718: dotoff--;
0719: d--;
0720: } else if (si == '.') {
0721: offset++; // step past dot
0722: dotoff--;
0723: } else if (si <= '9')
0724: break i;/* non-0 */
0725: else {/* exotic */
0726: if ((java.lang.Character.digit(si, 10)) != 0)
0727: break i; // non-0 or bad
0728: // is 0 .. strip like '0'
0729: offset++;
0730: dotoff--;
0731: d--;
0732: }
0733: }
0734: }/*i*/
0735:
0736: /* Create the mantissa array */
0737: mant = new byte[d]; // we know the length
0738: j = offset; // input offset
0739: if (exotic) {
0740: exotica: do { // slow: check for exotica
0741: {
0742: int $4 = d;
0743: i = 0;
0744: i: for (; $4 > 0; $4--, i++) {
0745: if (i == dotoff)
0746: j++; // at dot
0747: sj = inchars[j];
0748: if (sj <= '9')
0749: mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */
0750: else {
0751: dvalue = java.lang.Character.digit(sj, 10);
0752: if (dvalue < 0)
0753: bad(inchars); // not a number after all
0754: mant[i] = (byte) dvalue;
0755: }
0756: j++;
0757: }
0758: }/*i*/
0759: } while (false);
0760: }/*exotica*/
0761: else {
0762: simple: do {
0763: {
0764: int $5 = d;
0765: i = 0;
0766: i: for (; $5 > 0; $5--, i++) {
0767: if (i == dotoff)
0768: j++;
0769: mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0')));
0770: j++;
0771: }
0772: }/*i*/
0773: } while (false);
0774: }/*simple*/
0775:
0776: /* Looks good. Set the sign indicator and form, as needed. */
0777: // Trailing zeros are preserved
0778: // The rule here for form is:
0779: // If no E-notation, then request plain notation
0780: // Otherwise act as though add(0,DEFAULT) and request scientific notation
0781: // [form is already PLAIN]
0782: if (mant[0] == 0) {
0783: ind = iszero; // force to show zero
0784: // negative exponent is significant (e.g., -3 for 0.000) if plain
0785: if (exp > 0)
0786: exp = 0; // positive exponent can be ignored
0787: if (hadexp) { // zero becomes single digit from add
0788: mant = ZERO.mant;
0789: exp = 0;
0790: }
0791: } else { // non-zero
0792: // [ind was set earlier]
0793: // now determine form
0794: if (hadexp) {
0795: form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC;
0796: // 1999.06.29 check for overflow
0797: mag = (exp + mant.length) - 1; // true exponent in scientific notation
0798: if ((mag < MinExp) | (mag > MaxExp))
0799: bad(inchars);
0800: }
0801: }
0802: // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
0803: return;
0804: }
0805:
0806: /**
0807: * Constructs a <code>BigDecimal</code> object directly from a
0808: * <code>double</code>.
0809: * <p>
0810: * Constructs a <code>BigDecimal</code> which is the exact decimal
0811: * representation of the 64-bit signed binary floating point
0812: * parameter.
0813: * <p>
0814: * Note that this constructor it an exact conversion; it does not give
0815: * the same result as converting <code>num</code> to a
0816: * <code>String</code> using the <code>Double.toString()</code> method
0817: * and then using the {@link #BigDecimal(java.lang.String)}
0818: * constructor.
0819: * To get that result, use the static {@link #valueOf(double)}
0820: * method to construct a <code>BigDecimal</code> from a
0821: * <code>double</code>.
0822: *
0823: * @param num The <code>double</code> to be converted.
0824: * @throws NumberFormatException if the parameter is infinite or
0825: * not a number.
0826: * @stable ICU 2.0
0827: */
0828:
0829: public BigDecimal(double num) {
0830: // 1999.03.06: use exactly the old algorithm
0831: // 2000.01.01: note that this constructor does give an exact result,
0832: // so perhaps it should not be deprecated
0833: // 2000.06.18: no longer deprecated
0834: //#ifndef FOUNDATION
0835: this ((new java.math.BigDecimal(num)).toString());
0836: //#else
0837: //## this(String.valueOf(num));
0838: //#endif
0839: return;
0840: }
0841:
0842: /**
0843: * Constructs a <code>BigDecimal</code> object directly from a
0844: * <code>int</code>.
0845: * <p>
0846: * Constructs a <code>BigDecimal</code> which is the exact decimal
0847: * representation of the 32-bit signed binary integer parameter.
0848: * The <code>BigDecimal</code> will contain only decimal digits,
0849: * prefixed with a leading minus sign (hyphen) if the parameter is
0850: * negative.
0851: * A leading zero will be present only if the parameter is zero.
0852: *
0853: * @param num The <code>int</code> to be converted.
0854: * @stable ICU 2.0
0855: */
0856:
0857: public BigDecimal(int num) {
0858: super ();
0859: int mun;
0860: int i = 0;
0861: // We fastpath commoners
0862: if (num <= 9)
0863: if (num >= (-9)) {
0864: singledigit: do {
0865: // very common single digit case
0866: {/*select*/
0867: if (num == 0) {
0868: mant = ZERO.mant;
0869: ind = iszero;
0870: } else if (num == 1) {
0871: mant = ONE.mant;
0872: ind = ispos;
0873: } else if (num == (-1)) {
0874: mant = ONE.mant;
0875: ind = isneg;
0876: } else {
0877: {
0878: mant = new byte[1];
0879: if (num > 0) {
0880: mant[0] = (byte) num;
0881: ind = ispos;
0882: } else { // num<-1
0883: mant[0] = (byte) ((int) -num);
0884: ind = isneg;
0885: }
0886: }
0887: }
0888: }
0889: return;
0890: } while (false);
0891: }/*singledigit*/
0892:
0893: /* We work on negative numbers so we handle the most negative number */
0894: if (num > 0) {
0895: ind = ispos;
0896: num = (int) -num;
0897: } else
0898: ind = isneg;/* negative */// [0 case already handled]
0899: // [it is quicker, here, to pre-calculate the length with
0900: // one loop, then allocate exactly the right length of byte array,
0901: // then re-fill it with another loop]
0902: mun = num; // working copy
0903: {
0904: i = 9;
0905: i: for (;; i--) {
0906: mun = mun / 10;
0907: if (mun == 0)
0908: break i;
0909: }
0910: }/*i*/
0911: // i is the position of the leftmost digit placed
0912: mant = new byte[10 - i];
0913: {
0914: i = (10 - i) - 1;
0915: i: for (;; i--) {
0916: mant[i] = (byte) -(((byte) (num % 10)));
0917: num = num / 10;
0918: if (num == 0)
0919: break i;
0920: }
0921: }/*i*/
0922: return;
0923: }
0924:
0925: /**
0926: * Constructs a <code>BigDecimal</code> object directly from a
0927: * <code>long</code>.
0928: * <p>
0929: * Constructs a <code>BigDecimal</code> which is the exact decimal
0930: * representation of the 64-bit signed binary integer parameter.
0931: * The <code>BigDecimal</code> will contain only decimal digits,
0932: * prefixed with a leading minus sign (hyphen) if the parameter is
0933: * negative.
0934: * A leading zero will be present only if the parameter is zero.
0935: *
0936: * @param num The <code>long</code> to be converted.
0937: * @stable ICU 2.0
0938: */
0939:
0940: public BigDecimal(long num) {
0941: super ();
0942: long mun;
0943: int i = 0;
0944: // Not really worth fastpathing commoners in this constructor [also,
0945: // we use this to construct the static constants].
0946: // This is much faster than: this(String.valueOf(num).toCharArray())
0947: /* We work on negative num so we handle the most negative number */
0948: if (num > 0) {
0949: ind = ispos;
0950: num = (long) -num;
0951: } else if (num == 0)
0952: ind = iszero;
0953: else
0954: ind = isneg;/* negative */
0955: mun = num;
0956: {
0957: i = 18;
0958: i: for (;; i--) {
0959: mun = mun / 10;
0960: if (mun == 0)
0961: break i;
0962: }
0963: }/*i*/
0964: // i is the position of the leftmost digit placed
0965: mant = new byte[19 - i];
0966: {
0967: i = (19 - i) - 1;
0968: i: for (;; i--) {
0969: mant[i] = (byte) -(((byte) (num % 10)));
0970: num = num / 10;
0971: if (num == 0)
0972: break i;
0973: }
0974: }/*i*/
0975: return;
0976: }
0977:
0978: /**
0979: * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
0980: * <p>
0981: * Constructs a <code>BigDecimal</code> from the parameter, which must
0982: * not be <code>null</code> and must represent a valid <i>number</i>,
0983: * as described formally in the documentation referred to
0984: * {@link BigDecimal above}.
0985: * <p>
0986: * In summary, numbers in <code>String</code> form must have at least
0987: * one digit, may have a leading sign, may have a decimal point, and
0988: * exponential notation may be used. They follow conventional syntax,
0989: * and may not contain blanks.
0990: * <p>
0991: * Some valid strings from which a <code>BigDecimal</code> might
0992: * be constructed are:
0993: * <pre>
0994: * "0" -- Zero
0995: * "12" -- A whole number
0996: * "-76" -- A signed whole number
0997: * "12.70" -- Some decimal places
0998: * "+0.003" -- Plus sign is allowed
0999: * "17." -- The same as 17
1000: * ".5" -- The same as 0.5
1001: * "4E+9" -- Exponential notation
1002: * "0.73e-7" -- Exponential notation
1003: * </pre>
1004: * <p>
1005: * (Exponential notation means that the number includes an optional
1006: * sign and a power of ten following an '</code>E</code>' that
1007: * indicates how the decimal point will be shifted. Thus the
1008: * <code>"4E+9"</code> above is just a short way of writing
1009: * <code>4000000000</code>, and the <code>"0.73e-7"</code> is short
1010: * for <code>0.000000073</code>.)
1011: * <p>
1012: * The <code>BigDecimal</code> constructed from the String is in a
1013: * standard form, with no blanks, as though the
1014: * {@link #add(BigDecimal)} method had been used to add zero to the
1015: * number with unlimited precision.
1016: * If the string uses exponential notation (that is, includes an
1017: * <code>e</code> or an <code>E</code>), then the
1018: * <code>BigDecimal</code> number will be expressed in scientific
1019: * notation (where the power of ten is adjusted so there is a single
1020: * non-zero digit to the left of the decimal point); in this case if
1021: * the number is zero then it will be expressed as the single digit 0,
1022: * and if non-zero it will have an exponent unless that exponent would
1023: * be 0. The exponent must fit in nine digits both before and after it
1024: * is expressed in scientific notation.
1025: * <p>
1026: * Any digits in the parameter must be decimal; that is,
1027: * <code>Character.digit(c, 10)</code> (where </code>c</code> is the
1028: * character in question) would not return -1.
1029: *
1030: * @param string The <code>String</code> to be converted.
1031: * @throws NumberFormatException if the parameter is not a valid
1032: * number.
1033: * @stable ICU 2.0
1034: */
1035:
1036: public BigDecimal(java.lang.String string) {
1037: this (string.toCharArray(), 0, string.length());
1038: return;
1039: }
1040:
1041: /* <sgml> Make a default BigDecimal object for local use. </sgml> */
1042:
1043: private BigDecimal() {
1044: super ();
1045: return;
1046: }
1047:
1048: /* ---------------------------------------------------------------- */
1049: /* Operator methods [methods which take a context parameter] */
1050: /* ---------------------------------------------------------------- */
1051:
1052: /**
1053: * Returns a plain <code>BigDecimal</code> whose value is the absolute
1054: * value of this <code>BigDecimal</code>.
1055: * <p>
1056: * The same as {@link #abs(MathContext)}, where the context is
1057: * <code>new MathContext(0, MathContext.PLAIN)</code>.
1058: * <p>
1059: * The length of the decimal part (the scale) of the result will
1060: * be <code>this.scale()</code>
1061: *
1062: * @return A <code>BigDecimal</code> whose value is the absolute
1063: * value of this <code>BigDecimal</code>.
1064: * @stable ICU 2.0
1065: */
1066:
1067: public com.ibm.icu.math.BigDecimal abs() {
1068: return this .abs(plainMC);
1069: }
1070:
1071: /**
1072: * Returns a <code>BigDecimal</code> whose value is the absolute value
1073: * of this <code>BigDecimal</code>.
1074: * <p>
1075: * If the current object is zero or positive, then the same result as
1076: * invoking the {@link #plus(MathContext)} method with the same
1077: * parameter is returned.
1078: * Otherwise, the same result as invoking the
1079: * {@link #negate(MathContext)} method with the same parameter is
1080: * returned.
1081: *
1082: * @param set The <code>MathContext</code> arithmetic settings.
1083: * @return A <code>BigDecimal</code> whose value is the absolute
1084: * value of this <code>BigDecimal</code>.
1085: * @stable ICU 2.0
1086: */
1087:
1088: public com.ibm.icu.math.BigDecimal abs(
1089: com.ibm.icu.math.MathContext set) {
1090: if (this .ind == isneg)
1091: return this .negate(set);
1092: return this .plus(set);
1093: }
1094:
1095: /**
1096: * Returns a plain <code>BigDecimal</code> whose value is
1097: * <code>this+rhs</code>, using fixed point arithmetic.
1098: * <p>
1099: * The same as {@link #add(BigDecimal, MathContext)},
1100: * where the <code>BigDecimal</code> is <code>rhs</code>,
1101: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1102: * <p>
1103: * The length of the decimal part (the scale) of the result will be
1104: * the maximum of the scales of the two operands.
1105: *
1106: * @param rhs The <code>BigDecimal</code> for the right hand side of
1107: * the addition.
1108: * @return A <code>BigDecimal</code> whose value is
1109: * <code>this+rhs</code>, using fixed point arithmetic.
1110: * @stable ICU 2.0
1111: */
1112:
1113: public com.ibm.icu.math.BigDecimal add(
1114: com.ibm.icu.math.BigDecimal rhs) {
1115: return this .add(rhs, plainMC);
1116: }
1117:
1118: /**
1119: * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
1120: * <p>
1121: * Implements the addition (<b><code>+</code></b>) operator
1122: * (as defined in the decimal documentation, see {@link BigDecimal
1123: * class header}),
1124: * and returns the result as a <code>BigDecimal</code> object.
1125: *
1126: * @param rhs The <code>BigDecimal</code> for the right hand side of
1127: * the addition.
1128: * @param set The <code>MathContext</code> arithmetic settings.
1129: * @return A <code>BigDecimal</code> whose value is
1130: * <code>this+rhs</code>.
1131: * @stable ICU 2.0
1132: */
1133:
1134: public com.ibm.icu.math.BigDecimal add(
1135: com.ibm.icu.math.BigDecimal rhs,
1136: com.ibm.icu.math.MathContext set) {
1137: com.ibm.icu.math.BigDecimal lhs;
1138: int reqdig;
1139: com.ibm.icu.math.BigDecimal res;
1140: byte usel[];
1141: int usellen;
1142: byte user[];
1143: int userlen;
1144: int newlen = 0;
1145: int tlen = 0;
1146: int mult = 0;
1147: byte t[] = null;
1148: int ia = 0;
1149: int ib = 0;
1150: int ea = 0;
1151: int eb = 0;
1152: byte ca = 0;
1153: byte cb = 0;
1154: /* determine requested digits and form */
1155: if (set.lostDigits)
1156: checkdigits(rhs, set.digits);
1157: lhs = this ; // name for clarity and proxy
1158:
1159: /* Quick exit for add floating 0 */
1160: // plus() will optimize to return same object if possible
1161: if (lhs.ind == 0)
1162: if (set.form != com.ibm.icu.math.MathContext.PLAIN)
1163: return rhs.plus(set);
1164: if (rhs.ind == 0)
1165: if (set.form != com.ibm.icu.math.MathContext.PLAIN)
1166: return lhs.plus(set);
1167:
1168: /* Prepare numbers (round, unless unlimited precision) */
1169: reqdig = set.digits; // local copy (heavily used)
1170: if (reqdig > 0) {
1171: if (lhs.mant.length > reqdig)
1172: lhs = clone(lhs).round(set);
1173: if (rhs.mant.length > reqdig)
1174: rhs = clone(rhs).round(set);
1175: // [we could reuse the new LHS for result in this case]
1176: }
1177:
1178: res = new com.ibm.icu.math.BigDecimal(); // build result here
1179:
1180: /* Now see how much we have to pad or truncate lhs or rhs in order
1181: to align the numbers. If one number is much larger than the
1182: other, then the smaller cannot affect the answer [but we may
1183: still need to pad with up to DIGITS trailing zeros]. */
1184: // Note sign may be 0 if digits (reqdig) is 0
1185: // usel and user will be the byte arrays passed to the adder; we'll
1186: // use them on all paths except quick exits
1187: usel = lhs.mant;
1188: usellen = lhs.mant.length;
1189: user = rhs.mant;
1190: userlen = rhs.mant.length;
1191: {
1192: padder: do {/*select*/
1193: if (lhs.exp == rhs.exp) {/* no padding needed */
1194: // This is the most common, and fastest, path
1195: res.exp = lhs.exp;
1196: } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs
1197: newlen = (usellen + lhs.exp) - rhs.exp;
1198: /* If, after pad, lhs would be longer than rhs by digits+1 or
1199: more (and digits>0) then rhs cannot affect answer, so we only
1200: need to pad up to a length of DIGITS+1. */
1201: if (newlen >= ((userlen + reqdig) + 1))
1202: if (reqdig > 0) {
1203: // LHS is sufficient
1204: res.mant = usel;
1205: res.exp = lhs.exp;
1206: res.ind = lhs.ind;
1207: if (usellen < reqdig) { // need 0 padding
1208: res.mant = extend(lhs.mant, reqdig);
1209: res.exp = res.exp
1210: - ((reqdig - usellen));
1211: }
1212: return res.finish(set, false);
1213: }
1214: // RHS may affect result
1215: res.exp = rhs.exp; // expected final exponent
1216: if (newlen > (reqdig + 1))
1217: if (reqdig > 0) {
1218: // LHS will be max; RHS truncated
1219: tlen = (newlen - reqdig) - 1; // truncation length
1220: userlen = userlen - tlen;
1221: res.exp = res.exp + tlen;
1222: newlen = reqdig + 1;
1223: }
1224: if (newlen > usellen)
1225: usellen = newlen; // need to pad LHS
1226: } else { // need to pad rhs and/or truncate lhs
1227: newlen = (userlen + rhs.exp) - lhs.exp;
1228: if (newlen >= ((usellen + reqdig) + 1))
1229: if (reqdig > 0) {
1230: // RHS is sufficient
1231: res.mant = user;
1232: res.exp = rhs.exp;
1233: res.ind = rhs.ind;
1234: if (userlen < reqdig) { // need 0 padding
1235: res.mant = extend(rhs.mant, reqdig);
1236: res.exp = res.exp
1237: - ((reqdig - userlen));
1238: }
1239: return res.finish(set, false);
1240: }
1241: // LHS may affect result
1242: res.exp = lhs.exp; // expected final exponent
1243: if (newlen > (reqdig + 1))
1244: if (reqdig > 0) {
1245: // RHS will be max; LHS truncated
1246: tlen = (newlen - reqdig) - 1; // truncation length
1247: usellen = usellen - tlen;
1248: res.exp = res.exp + tlen;
1249: newlen = reqdig + 1;
1250: }
1251: if (newlen > userlen)
1252: userlen = newlen; // need to pad RHS
1253: }
1254: } while (false);
1255: }/*padder*/
1256:
1257: /* OK, we have aligned mantissas. Now add or subtract. */
1258: // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
1259: // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
1260: // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
1261: if (lhs.ind == iszero)
1262: res.ind = ispos;
1263: else
1264: res.ind = lhs.ind; // likely sign, all paths
1265: if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative
1266: mult = 1;
1267: else {
1268: signdiff: do { // different signs, so subtraction is needed
1269: mult = -1; // will cause subtract
1270: /* Before we can subtract we must determine which is the larger,
1271: as our add/subtract routine only handles non-negative results
1272: so we may need to swap the operands. */
1273: {
1274: swaptest: do {/*select*/
1275: if (rhs.ind == iszero) {
1276: // original A bigger
1277: } else if ((usellen < userlen)
1278: | (lhs.ind == iszero)) { // original B bigger
1279: t = usel;
1280: usel = user;
1281: user = t; // swap
1282: tlen = usellen;
1283: usellen = userlen;
1284: userlen = tlen; // ..
1285: res.ind = (byte) -res.ind; // and set sign
1286: } else if (usellen > userlen) {
1287: // original A bigger
1288: } else {
1289: {/* logical lengths the same */// need compare
1290: /* may still need to swap: compare the strings */
1291: ia = 0;
1292: ib = 0;
1293: ea = usel.length - 1;
1294: eb = user.length - 1;
1295: {
1296: compare: for (;;) {
1297: if (ia <= ea)
1298: ca = usel[ia];
1299: else {
1300: if (ib > eb) {/* identical */
1301: if (set.form != com.ibm.icu.math.MathContext.PLAIN)
1302: return ZERO;
1303: // [if PLAIN we must do the subtract, in case of 0.000 results]
1304: break compare;
1305: }
1306: ca = (byte) 0;
1307: }
1308: if (ib <= eb)
1309: cb = user[ib];
1310: else
1311: cb = (byte) 0;
1312: if (ca != cb) {
1313: if (ca < cb) {/* swap needed */
1314: t = usel;
1315: usel = user;
1316: user = t; // swap
1317: tlen = usellen;
1318: usellen = userlen;
1319: userlen = tlen; // ..
1320: res.ind = (byte) -res.ind;
1321: }
1322: break compare;
1323: }
1324: /* mantissas the same, so far */
1325: ia++;
1326: ib++;
1327: }
1328: }/*compare*/
1329: } // lengths the same
1330: }
1331: } while (false);
1332: }/*swaptest*/
1333: } while (false);
1334: }/*signdiff*/
1335:
1336: /* here, A is > B if subtracting */
1337: // add [A+B*1] or subtract [A+(B*-1)]
1338: res.mant = byteaddsub(usel, usellen, user, userlen, mult, false);
1339: // [reuse possible only after chop; accounting makes not worthwhile]
1340:
1341: // Finish() rounds before stripping leading 0's, then sets form, etc.
1342: return res.finish(set, false);
1343: }
1344:
1345: /**
1346: * Compares this <code>BigDecimal</code> to another, using unlimited
1347: * precision.
1348: * <p>
1349: * The same as {@link #compareTo(BigDecimal, MathContext)},
1350: * where the <code>BigDecimal</code> is <code>rhs</code>,
1351: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1352: *
1353: * @param rhs The <code>BigDecimal</code> for the right hand side of
1354: * the comparison.
1355: * @return An <code>int</code> whose value is -1, 0, or 1 as
1356: * <code>this</code> is numerically less than, equal to,
1357: * or greater than <code>rhs</code>.
1358: * @see #compareTo(Object)
1359: * @stable ICU 2.0
1360: */
1361:
1362: public int compareTo(com.ibm.icu.math.BigDecimal rhs) {
1363: return this .compareTo(rhs, plainMC);
1364: }
1365:
1366: /**
1367: * Compares this <code>BigDecimal</code> to another.
1368: * <p>
1369: * Implements numeric comparison,
1370: * (as defined in the decimal documentation, see {@link BigDecimal
1371: * class header}),
1372: * and returns a result of type <code>int</code>.
1373: * <p>
1374: * The result will be:
1375: * <table cellpadding=2><tr>
1376: * <td align=right><b>-1</b></td>
1377: * <td>if the current object is less than the first parameter</td>
1378: * </tr><tr>
1379: * <td align=right><b>0</b></td>
1380: * <td>if the current object is equal to the first parameter</td>
1381: * </tr><tr>
1382: * <td align=right><b>1</b></td>
1383: * <td>if the current object is greater than the first parameter.</td>
1384: * </tr></table>
1385: * <p>
1386: * A {@link #compareTo(Object)} method is also provided.
1387: *
1388: * @param rhs The <code>BigDecimal</code> for the right hand side of
1389: * the comparison.
1390: * @param set The <code>MathContext</code> arithmetic settings.
1391: * @return An <code>int</code> whose value is -1, 0, or 1 as
1392: * <code>this</code> is numerically less than, equal to,
1393: * or greater than <code>rhs</code>.
1394: * @see #compareTo(Object)
1395: * @stable ICU 2.0
1396: */
1397:
1398: public int compareTo(com.ibm.icu.math.BigDecimal rhs,
1399: com.ibm.icu.math.MathContext set) {
1400: int this length = 0;
1401: int i = 0;
1402: com.ibm.icu.math.BigDecimal newrhs;
1403: // rhs=null will raise NullPointerException, as per Comparable interface
1404: if (set.lostDigits)
1405: checkdigits(rhs, set.digits);
1406: // [add will recheck in slowpath cases .. but would report -rhs]
1407: if ((this .ind == rhs.ind) & (this .exp == rhs.exp)) {
1408: /* sign & exponent the same [very common] */
1409: this length = this .mant.length;
1410: if (this length < rhs.mant.length)
1411: return (byte) -this .ind;
1412: if (this length > rhs.mant.length)
1413: return this .ind;
1414: /* lengths are the same; we can do a straight mantissa compare
1415: unless maybe rounding [rounding is very unusual] */
1416: if ((this length <= set.digits) | (set.digits == 0)) {
1417: {
1418: int $6 = this length;
1419: i = 0;
1420: i: for (; $6 > 0; $6--, i++) {
1421: if (this .mant[i] < rhs.mant[i])
1422: return (byte) -this .ind;
1423: if (this .mant[i] > rhs.mant[i])
1424: return this .ind;
1425: }
1426: }/*i*/
1427: return 0; // identical
1428: }
1429: /* drop through for full comparison */
1430: } else {
1431: /* More fastpaths possible */
1432: if (this .ind < rhs.ind)
1433: return -1;
1434: if (this .ind > rhs.ind)
1435: return 1;
1436: }
1437: /* carry out a subtract to make the comparison */
1438: newrhs = clone(rhs); // safe copy
1439: newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
1440: return this .add(newrhs, set).ind; // add, and return sign of result
1441: }
1442:
1443: /**
1444: * Returns a plain <code>BigDecimal</code> whose value is
1445: * <code>this/rhs</code>, using fixed point arithmetic.
1446: * <p>
1447: * The same as {@link #divide(BigDecimal, int)},
1448: * where the <code>BigDecimal</code> is <code>rhs</code>,
1449: * and the rounding mode is {@link MathContext#ROUND_HALF_UP}.
1450: *
1451: * The length of the decimal part (the scale) of the result will be
1452: * the same as the scale of the current object, if the latter were
1453: * formatted without exponential notation.
1454: *
1455: * @param rhs The <code>BigDecimal</code> for the right hand side of
1456: * the division.
1457: * @return A plain <code>BigDecimal</code> whose value is
1458: * <code>this/rhs</code>, using fixed point arithmetic.
1459: * @throws ArithmeticException if <code>rhs</code> is zero.
1460: * @stable ICU 2.0
1461: */
1462:
1463: public com.ibm.icu.math.BigDecimal divide(
1464: com.ibm.icu.math.BigDecimal rhs) {
1465: return this .dodivide('D', rhs, plainMC, -1);
1466: }
1467:
1468: /**
1469: * Returns a plain <code>BigDecimal</code> whose value is
1470: * <code>this/rhs</code>, using fixed point arithmetic and a
1471: * rounding mode.
1472: * <p>
1473: * The same as {@link #divide(BigDecimal, int, int)},
1474: * where the <code>BigDecimal</code> is <code>rhs</code>,
1475: * and the second parameter is <code>this.scale()</code>, and
1476: * the third is <code>round</code>.
1477: * <p>
1478: * The length of the decimal part (the scale) of the result will
1479: * therefore be the same as the scale of the current object, if the
1480: * latter were formatted without exponential notation.
1481: * <p>
1482: * @param rhs The <code>BigDecimal</code> for the right hand side of
1483: * the division.
1484: * @param round The <code>int</code> rounding mode to be used for
1485: * the division (see the {@link MathContext} class).
1486: * @return A plain <code>BigDecimal</code> whose value is
1487: * <code>this/rhs</code>, using fixed point arithmetic
1488: * and the specified rounding mode.
1489: * @throws IllegalArgumentException if <code>round</code> is not a
1490: * valid rounding mode.
1491: * @throws ArithmeticException if <code>rhs</code> is zero.
1492: * @throws ArithmeticException if <code>round</code> is {@link
1493: * MathContext#ROUND_UNNECESSARY} and
1494: * <code>this.scale()</code> is insufficient to
1495: * represent the result exactly.
1496: * @stable ICU 2.0
1497: */
1498:
1499: public com.ibm.icu.math.BigDecimal divide(
1500: com.ibm.icu.math.BigDecimal rhs, int round) {
1501: com.ibm.icu.math.MathContext set;
1502: set = new com.ibm.icu.math.MathContext(0,
1503: com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round, too]
1504: return this .dodivide('D', rhs, set, -1); // take scale from LHS
1505: }
1506:
1507: /**
1508: * Returns a plain <code>BigDecimal</code> whose value is
1509: * <code>this/rhs</code>, using fixed point arithmetic and a
1510: * given scale and rounding mode.
1511: * <p>
1512: * The same as {@link #divide(BigDecimal, MathContext)},
1513: * where the <code>BigDecimal</code> is <code>rhs</code>,
1514: * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>,
1515: * except that the length of the decimal part (the scale) to be used
1516: * for the result is explicit rather than being taken from
1517: * <code>this</code>.
1518: * <p>
1519: * The length of the decimal part (the scale) of the result will be
1520: * the same as the scale of the current object, if the latter were
1521: * formatted without exponential notation.
1522: * <p>
1523: * @param rhs The <code>BigDecimal</code> for the right hand side of
1524: * the division.
1525: * @param scale The <code>int</code> scale to be used for the result.
1526: * @param round The <code>int</code> rounding mode to be used for
1527: * the division (see the {@link MathContext} class).
1528: * @return A plain <code>BigDecimal</code> whose value is
1529: * <code>this/rhs</code>, using fixed point arithmetic
1530: * and the specified rounding mode.
1531: * @throws IllegalArgumentException if <code>round</code> is not a
1532: * valid rounding mode.
1533: * @throws ArithmeticException if <code>rhs</code> is zero.
1534: * @throws ArithmeticException if <code>scale</code> is negative.
1535: * @throws ArithmeticException if <code>round</code> is {@link
1536: * MathContext#ROUND_UNNECESSARY} and <code>scale</code>
1537: * is insufficient to represent the result exactly.
1538: * @stable ICU 2.0
1539: */
1540:
1541: public com.ibm.icu.math.BigDecimal divide(
1542: com.ibm.icu.math.BigDecimal rhs, int scale, int round) {
1543: com.ibm.icu.math.MathContext set;
1544: if (scale < 0)
1545: throw new java.lang.ArithmeticException("Negative scale:"
1546: + " " + scale);
1547: set = new com.ibm.icu.math.MathContext(0,
1548: com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round]
1549: return this .dodivide('D', rhs, set, scale);
1550: }
1551:
1552: /**
1553: * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
1554: * <p>
1555: * Implements the division (<b><code>/</code></b>) operator
1556: * (as defined in the decimal documentation, see {@link BigDecimal
1557: * class header}),
1558: * and returns the result as a <code>BigDecimal</code> object.
1559: *
1560: * @param rhs The <code>BigDecimal</code> for the right hand side of
1561: * the division.
1562: * @param set The <code>MathContext</code> arithmetic settings.
1563: * @return A <code>BigDecimal</code> whose value is
1564: * <code>this/rhs</code>.
1565: * @throws ArithmeticException if <code>rhs</code> is zero.
1566: * @stable ICU 2.0
1567: */
1568:
1569: public com.ibm.icu.math.BigDecimal divide(
1570: com.ibm.icu.math.BigDecimal rhs,
1571: com.ibm.icu.math.MathContext set) {
1572: return this .dodivide('D', rhs, set, -1);
1573: }
1574:
1575: /**
1576: * Returns a plain <code>BigDecimal</code> whose value is the integer
1577: * part of <code>this/rhs</code>.
1578: * <p>
1579: * The same as {@link #divideInteger(BigDecimal, MathContext)},
1580: * where the <code>BigDecimal</code> is <code>rhs</code>,
1581: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1582: *
1583: * @param rhs The <code>BigDecimal</code> for the right hand side of
1584: * the integer division.
1585: * @return A <code>BigDecimal</code> whose value is the integer
1586: * part of <code>this/rhs</code>.
1587: * @throws ArithmeticException if <code>rhs</code> is zero.
1588: * @stable ICU 2.0
1589: */
1590:
1591: public com.ibm.icu.math.BigDecimal divideInteger(
1592: com.ibm.icu.math.BigDecimal rhs) {
1593: // scale 0 to drop .000 when plain
1594: return this .dodivide('I', rhs, plainMC, 0);
1595: }
1596:
1597: /**
1598: * Returns a <code>BigDecimal</code> whose value is the integer
1599: * part of <code>this/rhs</code>.
1600: * <p>
1601: * Implements the integer division operator
1602: * (as defined in the decimal documentation, see {@link BigDecimal
1603: * class header}),
1604: * and returns the result as a <code>BigDecimal</code> object.
1605: *
1606: * @param rhs The <code>BigDecimal</code> for the right hand side of
1607: * the integer division.
1608: * @param set The <code>MathContext</code> arithmetic settings.
1609: * @return A <code>BigDecimal</code> whose value is the integer
1610: * part of <code>this/rhs</code>.
1611: * @throws ArithmeticException if <code>rhs</code> is zero.
1612: * @throws ArithmeticException if the result will not fit in the
1613: * number of digits specified for the context.
1614: * @stable ICU 2.0
1615: */
1616:
1617: public com.ibm.icu.math.BigDecimal divideInteger(
1618: com.ibm.icu.math.BigDecimal rhs,
1619: com.ibm.icu.math.MathContext set) {
1620: // scale 0 to drop .000 when plain
1621: return this .dodivide('I', rhs, set, 0);
1622: }
1623:
1624: /**
1625: * Returns a plain <code>BigDecimal</code> whose value is
1626: * the maximum of <code>this</code> and <code>rhs</code>.
1627: * <p>
1628: * The same as {@link #max(BigDecimal, MathContext)},
1629: * where the <code>BigDecimal</code> is <code>rhs</code>,
1630: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1631: *
1632: * @param rhs The <code>BigDecimal</code> for the right hand side of
1633: * the comparison.
1634: * @return A <code>BigDecimal</code> whose value is
1635: * the maximum of <code>this</code> and <code>rhs</code>.
1636: * @stable ICU 2.0
1637: */
1638:
1639: public com.ibm.icu.math.BigDecimal max(
1640: com.ibm.icu.math.BigDecimal rhs) {
1641: return this .max(rhs, plainMC);
1642: }
1643:
1644: /**
1645: * Returns a <code>BigDecimal</code> whose value is
1646: * the maximum of <code>this</code> and <code>rhs</code>.
1647: * <p>
1648: * Returns the larger of the current object and the first parameter.
1649: * <p>
1650: * If calling the {@link #compareTo(BigDecimal, MathContext)} method
1651: * with the same parameters would return <code>1</code> or
1652: * <code>0</code>, then the result of calling the
1653: * {@link #plus(MathContext)} method on the current object (using the
1654: * same <code>MathContext</code> parameter) is returned.
1655: * Otherwise, the result of calling the {@link #plus(MathContext)}
1656: * method on the first parameter object (using the same
1657: * <code>MathContext</code> parameter) is returned.
1658: *
1659: * @param rhs The <code>BigDecimal</code> for the right hand side of
1660: * the comparison.
1661: * @param set The <code>MathContext</code> arithmetic settings.
1662: * @return A <code>BigDecimal</code> whose value is
1663: * the maximum of <code>this</code> and <code>rhs</code>.
1664: * @stable ICU 2.0
1665: */
1666:
1667: public com.ibm.icu.math.BigDecimal max(
1668: com.ibm.icu.math.BigDecimal rhs,
1669: com.ibm.icu.math.MathContext set) {
1670: if ((this .compareTo(rhs, set)) >= 0)
1671: return this .plus(set);
1672: else
1673: return rhs.plus(set);
1674: }
1675:
1676: /**
1677: * Returns a plain <code>BigDecimal</code> whose value is
1678: * the minimum of <code>this</code> and <code>rhs</code>.
1679: * <p>
1680: * The same as {@link #min(BigDecimal, MathContext)},
1681: * where the <code>BigDecimal</code> is <code>rhs</code>,
1682: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1683: *
1684: * @param rhs The <code>BigDecimal</code> for the right hand side of
1685: * the comparison.
1686: * @return A <code>BigDecimal</code> whose value is
1687: * the minimum of <code>this</code> and <code>rhs</code>.
1688: * @stable ICU 2.0
1689: */
1690:
1691: public com.ibm.icu.math.BigDecimal min(
1692: com.ibm.icu.math.BigDecimal rhs) {
1693: return this .min(rhs, plainMC);
1694: }
1695:
1696: /**
1697: * Returns a <code>BigDecimal</code> whose value is
1698: * the minimum of <code>this</code> and <code>rhs</code>.
1699: * <p>
1700: * Returns the smaller of the current object and the first parameter.
1701: * <p>
1702: * If calling the {@link #compareTo(BigDecimal, MathContext)} method
1703: * with the same parameters would return <code>-1</code> or
1704: * <code>0</code>, then the result of calling the
1705: * {@link #plus(MathContext)} method on the current object (using the
1706: * same <code>MathContext</code> parameter) is returned.
1707: * Otherwise, the result of calling the {@link #plus(MathContext)}
1708: * method on the first parameter object (using the same
1709: * <code>MathContext</code> parameter) is returned.
1710: *
1711: * @param rhs The <code>BigDecimal</code> for the right hand side of
1712: * the comparison.
1713: * @param set The <code>MathContext</code> arithmetic settings.
1714: * @return A <code>BigDecimal</code> whose value is
1715: * the minimum of <code>this</code> and <code>rhs</code>.
1716: * @stable ICU 2.0
1717: */
1718:
1719: public com.ibm.icu.math.BigDecimal min(
1720: com.ibm.icu.math.BigDecimal rhs,
1721: com.ibm.icu.math.MathContext set) {
1722: if ((this .compareTo(rhs, set)) <= 0)
1723: return this .plus(set);
1724: else
1725: return rhs.plus(set);
1726: }
1727:
1728: /**
1729: * Returns a plain <code>BigDecimal</code> whose value is
1730: * <code>this*rhs</code>, using fixed point arithmetic.
1731: * <p>
1732: * The same as {@link #add(BigDecimal, MathContext)},
1733: * where the <code>BigDecimal</code> is <code>rhs</code>,
1734: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1735: * <p>
1736: * The length of the decimal part (the scale) of the result will be
1737: * the sum of the scales of the operands, if they were formatted
1738: * without exponential notation.
1739: *
1740: * @param rhs The <code>BigDecimal</code> for the right hand side of
1741: * the multiplication.
1742: * @return A <code>BigDecimal</code> whose value is
1743: * <code>this*rhs</code>, using fixed point arithmetic.
1744: * @stable ICU 2.0
1745: */
1746:
1747: public com.ibm.icu.math.BigDecimal multiply(
1748: com.ibm.icu.math.BigDecimal rhs) {
1749: return this .multiply(rhs, plainMC);
1750: }
1751:
1752: /**
1753: * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
1754: * <p>
1755: * Implements the multiplication (<b><code>*</code></b>) operator
1756: * (as defined in the decimal documentation, see {@link BigDecimal
1757: * class header}),
1758: * and returns the result as a <code>BigDecimal</code> object.
1759: *
1760: * @param rhs The <code>BigDecimal</code> for the right hand side of
1761: * the multiplication.
1762: * @param set The <code>MathContext</code> arithmetic settings.
1763: * @return A <code>BigDecimal</code> whose value is
1764: * <code>this*rhs</code>.
1765: * @stable ICU 2.0
1766: */
1767:
1768: public com.ibm.icu.math.BigDecimal multiply(
1769: com.ibm.icu.math.BigDecimal rhs,
1770: com.ibm.icu.math.MathContext set) {
1771: com.ibm.icu.math.BigDecimal lhs;
1772: int padding;
1773: int reqdig;
1774: byte multer[] = null;
1775: byte multand[] = null;
1776: int multandlen;
1777: int acclen = 0;
1778: com.ibm.icu.math.BigDecimal res;
1779: byte acc[];
1780: int n = 0;
1781: byte mult = 0;
1782: if (set.lostDigits)
1783: checkdigits(rhs, set.digits);
1784: lhs = this ; // name for clarity and proxy
1785:
1786: /* Prepare numbers (truncate, unless unlimited precision) */
1787: padding = 0; // trailing 0's to add
1788: reqdig = set.digits; // local copy
1789: if (reqdig > 0) {
1790: if (lhs.mant.length > reqdig)
1791: lhs = clone(lhs).round(set);
1792: if (rhs.mant.length > reqdig)
1793: rhs = clone(rhs).round(set);
1794: // [we could reuse the new LHS for result in this case]
1795: } else {/* unlimited */
1796: // fixed point arithmetic will want every trailing 0; we add these
1797: // after the calculation rather than before, for speed.
1798: if (lhs.exp > 0)
1799: padding = padding + lhs.exp;
1800: if (rhs.exp > 0)
1801: padding = padding + rhs.exp;
1802: }
1803:
1804: // For best speed, as in DMSRCN, we use the shorter number as the
1805: // multiplier and the longer as the multiplicand.
1806: // 1999.12.22: We used to special case when the result would fit in
1807: // a long, but with Java 1.3 this gave no advantage.
1808: if (lhs.mant.length < rhs.mant.length) {
1809: multer = lhs.mant;
1810: multand = rhs.mant;
1811: } else {
1812: multer = rhs.mant;
1813: multand = lhs.mant;
1814: }
1815:
1816: /* Calculate how long result byte array will be */
1817: multandlen = (multer.length + multand.length) - 1; // effective length
1818: // optimize for 75% of the cases where a carry is expected...
1819: if ((multer[0] * multand[0]) > 9)
1820: acclen = multandlen + 1;
1821: else
1822: acclen = multandlen;
1823:
1824: /* Now the main long multiplication loop */
1825: res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
1826: acc = new byte[acclen]; // accumulator, all zeros
1827: // 1998.07.01: calculate from left to right so that accumulator goes
1828: // to likely final length on first addition; this avoids a one-digit
1829: // extension (and object allocation) each time around the loop.
1830: // Initial number therefore has virtual zeros added to right.
1831: {
1832: int $7 = multer.length;
1833: n = 0;
1834: n: for (; $7 > 0; $7--, n++) {
1835: mult = multer[n];
1836: if (mult != 0) { // [optimization]
1837: // accumulate [accumulator is reusable array]
1838: acc = byteaddsub(acc, acc.length, multand,
1839: multandlen, mult, true);
1840: }
1841: // divide multiplicand by 10 for next digit to right
1842: multandlen--; // 'virtual length'
1843: }
1844: }/*n*/
1845:
1846: res.ind = (byte) (lhs.ind * rhs.ind); // final sign
1847: res.exp = (lhs.exp + rhs.exp) - padding; // final exponent
1848: // [overflow is checked by finish]
1849:
1850: /* add trailing zeros to the result, if necessary */
1851: if (padding == 0)
1852: res.mant = acc;
1853: else
1854: res.mant = extend(acc, acc.length + padding); // add trailing 0s
1855: return res.finish(set, false);
1856: }
1857:
1858: /**
1859: * Returns a plain <code>BigDecimal</code> whose value is
1860: * <code>-this</code>.
1861: * <p>
1862: * The same as {@link #negate(MathContext)}, where the context is
1863: * <code>new MathContext(0, MathContext.PLAIN)</code>.
1864: * <p>
1865: * The length of the decimal part (the scale) of the result will be
1866: * be <code>this.scale()</code>
1867: *
1868: *
1869: * @return A <code>BigDecimal</code> whose value is
1870: * <code>-this</code>.
1871: * @stable ICU 2.0
1872: */
1873:
1874: public com.ibm.icu.math.BigDecimal negate() {
1875: return this .negate(plainMC);
1876: }
1877:
1878: /**
1879: * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
1880: * <p>
1881: * Implements the negation (Prefix <b><code>-</code></b>) operator
1882: * (as defined in the decimal documentation, see {@link BigDecimal
1883: * class header}),
1884: * and returns the result as a <code>BigDecimal</code> object.
1885: *
1886: * @param set The <code>MathContext</code> arithmetic settings.
1887: * @return A <code>BigDecimal</code> whose value is
1888: * <code>-this</code>.
1889: * @stable ICU 2.0
1890: */
1891:
1892: public com.ibm.icu.math.BigDecimal negate(
1893: com.ibm.icu.math.MathContext set) {
1894: com.ibm.icu.math.BigDecimal res;
1895: // Originally called minus(), changed to matched Java precedents
1896: // This simply clones, flips the sign, and possibly rounds
1897: if (set.lostDigits)
1898: checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
1899: res = clone(this ); // safe copy
1900: res.ind = (byte) -res.ind;
1901: return res.finish(set, false);
1902: }
1903:
1904: /**
1905: * Returns a plain <code>BigDecimal</code> whose value is
1906: * <code>+this</code>.
1907: * Note that <code>this</code> is not necessarily a
1908: * plain <code>BigDecimal</code>, but the result will always be.
1909: * <p>
1910: * The same as {@link #plus(MathContext)}, where the context is
1911: * <code>new MathContext(0, MathContext.PLAIN)</code>.
1912: * <p>
1913: * The length of the decimal part (the scale) of the result will be
1914: * be <code>this.scale()</code>
1915: *
1916: * @return A <code>BigDecimal</code> whose value is
1917: * <code>+this</code>.
1918: * @stable ICU 2.0
1919: */
1920:
1921: public com.ibm.icu.math.BigDecimal plus() {
1922: return this .plus(plainMC);
1923: }
1924:
1925: /**
1926: * Returns a <code>BigDecimal</code> whose value is
1927: * <code>+this</code>.
1928: * <p>
1929: * Implements the plus (Prefix <b><code>+</code></b>) operator
1930: * (as defined in the decimal documentation, see {@link BigDecimal
1931: * class header}),
1932: * and returns the result as a <code>BigDecimal</code> object.
1933: * <p>
1934: * This method is useful for rounding or otherwise applying a context
1935: * to a decimal value.
1936: *
1937: * @param set The <code>MathContext</code> arithmetic settings.
1938: * @return A <code>BigDecimal</code> whose value is
1939: * <code>+this</code>.
1940: * @stable ICU 2.0
1941: */
1942:
1943: public com.ibm.icu.math.BigDecimal plus(
1944: com.ibm.icu.math.MathContext set) {
1945: // This clones and forces the result to the new settings
1946: // May return same object
1947: if (set.lostDigits)
1948: checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
1949: // Optimization: returns same object for some common cases
1950: if (set.form == com.ibm.icu.math.MathContext.PLAIN)
1951: if (this .form == com.ibm.icu.math.MathContext.PLAIN) {
1952: if (this .mant.length <= set.digits)
1953: return this ;
1954: if (set.digits == 0)
1955: return this ;
1956: }
1957: return clone(this ).finish(set, false);
1958: }
1959:
1960: /**
1961: * Returns a plain <code>BigDecimal</code> whose value is
1962: * <code>this**rhs</code>, using fixed point arithmetic.
1963: * <p>
1964: * The same as {@link #pow(BigDecimal, MathContext)},
1965: * where the <code>BigDecimal</code> is <code>rhs</code>,
1966: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
1967: * <p>
1968: * The parameter is the power to which the <code>this</code> will be
1969: * raised; it must be in the range 0 through 999999999, and must
1970: * have a decimal part of zero. Note that these restrictions may be
1971: * removed in the future, so they should not be used as a test for a
1972: * whole number.
1973: * <p>
1974: * In addition, the power must not be negative, as no
1975: * <code>MathContext</code> is used and so the result would then
1976: * always be 0.
1977: *
1978: * @param rhs The <code>BigDecimal</code> for the right hand side of
1979: * the operation (the power).
1980: * @return A <code>BigDecimal</code> whose value is
1981: * <code>this**rhs</code>, using fixed point arithmetic.
1982: * @throws ArithmeticException if <code>rhs</code> is out of range or
1983: * is not a whole number.
1984: * @stable ICU 2.0
1985: */
1986:
1987: public com.ibm.icu.math.BigDecimal pow(
1988: com.ibm.icu.math.BigDecimal rhs) {
1989: return this .pow(rhs, plainMC);
1990: }
1991:
1992: // The name for this method is inherited from the precedent set by the
1993: // BigInteger and Math classes.
1994:
1995: /**
1996: * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
1997: * <p>
1998: * Implements the power (<b><code>**</code></b>) operator
1999: * (as defined in the decimal documentation, see {@link BigDecimal
2000: * class header}),
2001: * and returns the result as a <code>BigDecimal</code> object.
2002: * <p>
2003: * The first parameter is the power to which the <code>this</code>
2004: * will be raised; it must be in the range -999999999 through
2005: * 999999999, and must have a decimal part of zero. Note that these
2006: * restrictions may be removed in the future, so they should not be
2007: * used as a test for a whole number.
2008: * <p>
2009: * If the <code>digits</code> setting of the <code>MathContext</code>
2010: * parameter is 0, the power must be zero or positive.
2011: *
2012: * @param rhs The <code>BigDecimal</code> for the right hand side of
2013: * the operation (the power).
2014: * @param set The <code>MathContext</code> arithmetic settings.
2015: * @return A <code>BigDecimal</code> whose value is
2016: * <code>this**rhs</code>.
2017: * @throws ArithmeticException if <code>rhs</code> is out of range or
2018: * is not a whole number.
2019: * @stable ICU 2.0
2020: */
2021:
2022: public com.ibm.icu.math.BigDecimal pow(
2023: com.ibm.icu.math.BigDecimal rhs,
2024: com.ibm.icu.math.MathContext set) {
2025: int n;
2026: com.ibm.icu.math.BigDecimal lhs;
2027: int reqdig;
2028: int workdigits = 0;
2029: int L = 0;
2030: com.ibm.icu.math.MathContext workset;
2031: com.ibm.icu.math.BigDecimal res;
2032: boolean seenbit;
2033: int i = 0;
2034: if (set.lostDigits)
2035: checkdigits(rhs, set.digits);
2036: n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules
2037: lhs = this ; // clarified name
2038:
2039: reqdig = set.digits; // local copy (heavily used)
2040: if (reqdig == 0) {
2041: if (rhs.ind == isneg)
2042: throw new java.lang.ArithmeticException(
2043: "Negative power:" + " " + rhs.toString());
2044: workdigits = 0;
2045: } else {/* non-0 digits */
2046: if ((rhs.mant.length + rhs.exp) > reqdig)
2047: throw new java.lang.ArithmeticException(
2048: "Too many digits:" + " " + rhs.toString());
2049:
2050: /* Round the lhs to DIGITS if need be */
2051: if (lhs.mant.length > reqdig)
2052: lhs = clone(lhs).round(set);
2053:
2054: /* L for precision calculation [see ANSI X3.274-1996] */
2055: L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp
2056: workdigits = (reqdig + L) + 1; // calculate the working DIGITS
2057: }
2058:
2059: /* Create a copy of set for working settings */
2060: // Note: no need to check for lostDigits again.
2061: // 1999.07.17 Note: this construction must follow RHS check
2062: workset = new com.ibm.icu.math.MathContext(workdigits,
2063: set.form, false, set.roundingMode);
2064:
2065: res = ONE; // accumulator
2066: if (n == 0)
2067: return res; // x**0 == 1
2068: if (n < 0)
2069: n = (int) -n; // [rhs.ind records the sign]
2070: seenbit = false; // set once we've seen a 1-bit
2071: {
2072: i = 1;
2073: i: for (;; i++) { // for each bit [top bit ignored]
2074: n = n + n; // shift left 1 bit
2075: if (n < 0) { // top bit is set
2076: seenbit = true; // OK, we're off
2077: res = res.multiply(lhs, workset); // acc=acc*x
2078: }
2079: if (i == 31)
2080: break i; // that was the last bit
2081: if ((!seenbit))
2082: continue i; // we don't have to square 1
2083: res = res.multiply(res, workset); // acc=acc*acc [square]
2084: }
2085: }/*i*/// 32 bits
2086: if (rhs.ind < 0) // was a **-n [hence digits>0]
2087: res = ONE.divide(res, workset); // .. so acc=1/acc
2088: return res.finish(set, true); // round and strip [original digits]
2089: }
2090:
2091: /**
2092: * Returns a plain <code>BigDecimal</code> whose value is
2093: * the remainder of <code>this/rhs</code>, using fixed point arithmetic.
2094: * <p>
2095: * The same as {@link #remainder(BigDecimal, MathContext)},
2096: * where the <code>BigDecimal</code> is <code>rhs</code>,
2097: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
2098: * <p>
2099: * This is not the modulo operator -- the result may be negative.
2100: *
2101: * @param rhs The <code>BigDecimal</code> for the right hand side of
2102: * the remainder operation.
2103: * @return A <code>BigDecimal</code> whose value is the remainder
2104: * of <code>this/rhs</code>, using fixed point arithmetic.
2105: * @throws ArithmeticException if <code>rhs</code> is zero.
2106: * @stable ICU 2.0
2107: */
2108:
2109: public com.ibm.icu.math.BigDecimal remainder(
2110: com.ibm.icu.math.BigDecimal rhs) {
2111: return this .dodivide('R', rhs, plainMC, -1);
2112: }
2113:
2114: /**
2115: * Returns a <code>BigDecimal</code> whose value is the remainder of
2116: * <code>this/rhs</code>.
2117: * <p>
2118: * Implements the remainder operator
2119: * (as defined in the decimal documentation, see {@link BigDecimal
2120: * class header}),
2121: * and returns the result as a <code>BigDecimal</code> object.
2122: * <p>
2123: * This is not the modulo operator -- the result may be negative.
2124: *
2125: * @param rhs The <code>BigDecimal</code> for the right hand side of
2126: * the remainder operation.
2127: * @param set The <code>MathContext</code> arithmetic settings.
2128: * @return A <code>BigDecimal</code> whose value is the remainder
2129: * of <code>this+rhs</code>.
2130: * @throws ArithmeticException if <code>rhs</code> is zero.
2131: * @throws ArithmeticException if the integer part of the result will
2132: * not fit in the number of digits specified for the
2133: * context.
2134: * @stable ICU 2.0
2135: */
2136:
2137: public com.ibm.icu.math.BigDecimal remainder(
2138: com.ibm.icu.math.BigDecimal rhs,
2139: com.ibm.icu.math.MathContext set) {
2140: return this .dodivide('R', rhs, set, -1);
2141: }
2142:
2143: /**
2144: * Returns a plain <code>BigDecimal</code> whose value is
2145: * <code>this-rhs</code>, using fixed point arithmetic.
2146: * <p>
2147: * The same as {@link #subtract(BigDecimal, MathContext)},
2148: * where the <code>BigDecimal</code> is <code>rhs</code>,
2149: * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
2150: * <p>
2151: * The length of the decimal part (the scale) of the result will be
2152: * the maximum of the scales of the two operands.
2153: *
2154: * @param rhs The <code>BigDecimal</code> for the right hand side of
2155: * the subtraction.
2156: * @return A <code>BigDecimal</code> whose value is
2157: * <code>this-rhs</code>, using fixed point arithmetic.
2158: * @stable ICU 2.0
2159: */
2160:
2161: public com.ibm.icu.math.BigDecimal subtract(
2162: com.ibm.icu.math.BigDecimal rhs) {
2163: return this .subtract(rhs, plainMC);
2164: }
2165:
2166: /**
2167: * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
2168: * <p>
2169: * Implements the subtraction (<b><code>-</code></b>) operator
2170: * (as defined in the decimal documentation, see {@link BigDecimal
2171: * class header}),
2172: * and returns the result as a <code>BigDecimal</code> object.
2173: *
2174: * @param rhs The <code>BigDecimal</code> for the right hand side of
2175: * the subtraction.
2176: * @param set The <code>MathContext</code> arithmetic settings.
2177: * @return A <code>BigDecimal</code> whose value is
2178: * <code>this-rhs</code>.
2179: * @stable ICU 2.0
2180: */
2181:
2182: public com.ibm.icu.math.BigDecimal subtract(
2183: com.ibm.icu.math.BigDecimal rhs,
2184: com.ibm.icu.math.MathContext set) {
2185: com.ibm.icu.math.BigDecimal newrhs;
2186: if (set.lostDigits)
2187: checkdigits(rhs, set.digits);
2188: // [add will recheck .. but would report -rhs]
2189: /* carry out the subtraction */
2190: // we could fastpath -0, but it is too rare.
2191: newrhs = clone(rhs); // safe copy
2192: newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
2193: return this .add(newrhs, set); // arithmetic
2194: }
2195:
2196: /* ---------------------------------------------------------------- */
2197: /* Other methods */
2198: /* ---------------------------------------------------------------- */
2199:
2200: /**
2201: * Converts this <code>BigDecimal</code> to a <code>byte</code>.
2202: * If the <code>BigDecimal</code> has a non-zero decimal part or is
2203: * out of the possible range for a <code>byte</code> (8-bit signed
2204: * integer) result then an <code>ArithmeticException</code> is thrown.
2205: *
2206: * @return A <code>byte</code> equal in value to <code>this</code>.
2207: * @throws ArithmeticException if <code>this</code> has a non-zero
2208: * decimal part, or will not fit in a <code>byte</code>.
2209: * @stable ICU 2.0
2210: */
2211:
2212: public byte byteValueExact() {
2213: int num;
2214: num = this .intValueExact(); // will check decimal part too
2215: if ((num > 127) | (num < (-128)))
2216: throw new java.lang.ArithmeticException(
2217: "Conversion overflow:" + " " + this .toString());
2218: return (byte) num;
2219: }
2220:
2221: /**
2222: * Compares this <code>BigDecimal</code> with the value of the parameter.
2223: * <p>
2224: * If the parameter is <code>null</code>, or is not an instance of the
2225: * <code>BigDecimal</code> type, an exception is thrown.
2226: * Otherwise, the parameter is cast to type <code>BigDecimal</code>
2227: * and the result of the {@link #compareTo(BigDecimal)} method,
2228: * using the cast parameter, is returned.
2229: * <p>
2230: * The {@link #compareTo(BigDecimal, MathContext)} method should be
2231: * used when a <code>MathContext</code> is needed for the comparison.
2232: *
2233: * @param rhsobj The <code>Object</code> for the right hand side of
2234: * the comparison.
2235: * @return An <code>int</code> whose value is -1, 0, or 1 as
2236: * <code>this</code> is numerically less than, equal to,
2237: * or greater than <code>rhs</code>.
2238: * @throws ClassCastException if <code>rhs</code> cannot be cast to
2239: * a <code>BigDecimal</code> object.
2240: * @see #compareTo(BigDecimal)
2241: * @stable ICU 2.0
2242: */
2243:
2244: public int compareTo(java.lang.Object rhsobj) {
2245: // the cast in the next line will raise ClassCastException if necessary
2246: return compareTo((com.ibm.icu.math.BigDecimal) rhsobj, plainMC);
2247: }
2248:
2249: /**
2250: * Converts this <code>BigDecimal</code> to a <code>double</code>.
2251: * If the <code>BigDecimal</code> is out of the possible range for a
2252: * <code>double</code> (64-bit signed floating point) result then an
2253: * <code>ArithmeticException</code> is thrown.
2254: * <p>
2255: * The double produced is identical to result of expressing the
2256: * <code>BigDecimal</code> as a <code>String</code> and then
2257: * converting it using the <code>Double(String)</code> constructor;
2258: * this can result in values of <code>Double.NEGATIVE_INFINITY</code>
2259: * or <code>Double.POSITIVE_INFINITY</code>.
2260: *
2261: * @return A <code>double</code> corresponding to <code>this</code>.
2262: * @stable ICU 2.0
2263: */
2264:
2265: public double doubleValue() {
2266: // We go via a String [as does BigDecimal in JDK 1.2]
2267: // Next line could possibly raise NumberFormatException
2268: return java.lang.Double.valueOf(this .toString()).doubleValue();
2269: }
2270:
2271: /**
2272: * Compares this <code>BigDecimal</code> with <code>rhs</code> for
2273: * equality.
2274: * <p>
2275: * If the parameter is <code>null</code>, or is not an instance of the
2276: * BigDecimal type, or is not exactly equal to the current
2277: * <code>BigDecimal</code> object, then <i>false</i> is returned.
2278: * Otherwise, <i>true</i> is returned.
2279: * <p>
2280: * "Exactly equal", here, means that the <code>String</code>
2281: * representations of the <code>BigDecimal</code> numbers are
2282: * identical (they have the same characters in the same sequence).
2283: * <p>
2284: * The {@link #compareTo(BigDecimal, MathContext)} method should be
2285: * used for more general comparisons.
2286: * @param obj The <code>Object</code> for the right hand side of
2287: * the comparison.
2288: * @return A <code>boolean</code> whose value <i>true</i> if and
2289: * only if the operands have identical string representations.
2290: * @throws ClassCastException if <code>rhs</code> cannot be cast to
2291: * a <code>BigDecimal</code> object.
2292: * @stable ICU 2.0
2293: * @see #compareTo(Object)
2294: * @see #compareTo(BigDecimal)
2295: * @see #compareTo(BigDecimal, MathContext)
2296: */
2297:
2298: public boolean equals(java.lang.Object obj) {
2299: com.ibm.icu.math.BigDecimal rhs;
2300: int i = 0;
2301: char lca[] = null;
2302: char rca[] = null;
2303: // We are equal iff toString of both are exactly the same
2304: if (obj == null)
2305: return false; // not equal
2306: if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
2307: return false; // not a decimal
2308: rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work
2309: if (this .ind != rhs.ind)
2310: return false; // different signs never match
2311: if (((this .mant.length == rhs.mant.length) & (this .exp == rhs.exp))
2312: & (this .form == rhs.form))
2313:
2314: { // mantissas say all
2315: // here with equal-length byte arrays to compare
2316: {
2317: int $8 = this .mant.length;
2318: i = 0;
2319: i: for (; $8 > 0; $8--, i++) {
2320: if (this .mant[i] != rhs.mant[i])
2321: return false;
2322: }
2323: }/*i*/
2324: } else { // need proper layout
2325: lca = this .layout(); // layout to character array
2326: rca = rhs.layout();
2327: if (lca.length != rca.length)
2328: return false; // mismatch
2329: // here with equal-length character arrays to compare
2330: {
2331: int $9 = lca.length;
2332: i = 0;
2333: i: for (; $9 > 0; $9--, i++) {
2334: if (lca[i] != rca[i])
2335: return false;
2336: }
2337: }/*i*/
2338: }
2339: return true; // arrays have identical content
2340: }
2341:
2342: /**
2343: * Converts this <code>BigDecimal</code> to a <code>float</code>.
2344: * If the <code>BigDecimal</code> is out of the possible range for a
2345: * <code>float</code> (32-bit signed floating point) result then an
2346: * <code>ArithmeticException</code> is thrown.
2347: * <p>
2348: * The float produced is identical to result of expressing the
2349: * <code>BigDecimal</code> as a <code>String</code> and then
2350: * converting it using the <code>Float(String)</code> constructor;
2351: * this can result in values of <code>Float.NEGATIVE_INFINITY</code>
2352: * or <code>Float.POSITIVE_INFINITY</code>.
2353: *
2354: * @return A <code>float</code> corresponding to <code>this</code>.
2355: * @stable ICU 2.0
2356: */
2357:
2358: public float floatValue() {
2359: return java.lang.Float.valueOf(this .toString()).floatValue();
2360: }
2361:
2362: /**
2363: * Returns the <code>String</code> representation of this
2364: * <code>BigDecimal</code>, modified by layout parameters.
2365: * <p>
2366: * <i>This method is provided as a primitive for use by more
2367: * sophisticated classes, such as <code>DecimalFormat</code>, that
2368: * can apply locale-sensitive editing of the result. The level of
2369: * formatting that it provides is a necessary part of the BigDecimal
2370: * class as it is sensitive to and must follow the calculation and
2371: * rounding rules for BigDecimal arithmetic.
2372: * However, if the function is provided elsewhere, it may be removed
2373: * from this class. </i>
2374: * <p>
2375: * The parameters, for both forms of the <code>format</code> method
2376: * are all of type <code>int</code>.
2377: * A value of -1 for any parameter indicates that the default action
2378: * or value for that parameter should be used.
2379: * <p>
2380: * The parameters, <code>before</code> and <code>after</code>,
2381: * specify the number of characters to be used for the integer part
2382: * and decimal part of the result respectively. Exponential notation
2383: * is not used. If either parameter is -1 (which indicates the default
2384: * action), the number of characters used will be exactly as many as
2385: * are needed for that part.
2386: * <p>
2387: * <code>before</code> must be a positive number; if it is larger than
2388: * is needed to contain the integer part, that part is padded on the
2389: * left with blanks to the requested length. If <code>before</code> is
2390: * not large enough to contain the integer part of the number
2391: * (including the sign, for negative numbers) an exception is thrown.
2392: * <p>
2393: * <code>after</code> must be a non-negative number; if it is not the
2394: * same size as the decimal part of the number, the number will be
2395: * rounded (or extended with zeros) to fit. Specifying 0 for
2396: * <code>after</code> will cause the number to be rounded to an
2397: * integer (that is, it will have no decimal part or decimal point).
2398: * The rounding method will be the default,
2399: * <code>MathContext.ROUND_HALF_UP</code>.
2400: * <p>
2401: * Other rounding methods, and the use of exponential notation, can
2402: * be selected by using {@link #format(int,int,int,int,int,int)}.
2403: * Using the two-parameter form of the method has exactly the same
2404: * effect as using the six-parameter form with the final four
2405: * parameters all being -1.
2406: *
2407: * @param before The <code>int</code> specifying the number of places
2408: * before the decimal point. Use -1 for 'as many as
2409: * are needed'.
2410: * @param after The <code>int</code> specifying the number of places
2411: * after the decimal point. Use -1 for 'as many as are
2412: * needed'.
2413: * @return A <code>String</code> representing this
2414: * <code>BigDecimal</code>, laid out according to the
2415: * specified parameters
2416: * @throws ArithmeticException if the number cannot be laid out as
2417: * requested.
2418: * @throws IllegalArgumentException if a parameter is out of range.
2419: * @stable ICU 2.0
2420: * @see #toString
2421: * @see #toCharArray
2422: */
2423:
2424: public java.lang.String format(int before, int after) {
2425: return format(before, after, -1, -1,
2426: com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP);
2427: }
2428:
2429: /**
2430: * Returns the <code>String</code> representation of this
2431: * <code>BigDecimal</code>, modified by layout parameters and allowing
2432: * exponential notation.
2433: * <p>
2434: * <i>This method is provided as a primitive for use by more
2435: * sophisticated classes, such as <code>DecimalFormat</code>, that
2436: * can apply locale-sensitive editing of the result. The level of
2437: * formatting that it provides is a necessary part of the BigDecimal
2438: * class as it is sensitive to and must follow the calculation and
2439: * rounding rules for BigDecimal arithmetic.
2440: * However, if the function is provided elsewhere, it may be removed
2441: * from this class. </i>
2442: * <p>
2443: * The parameters are all of type <code>int</code>.
2444: * A value of -1 for any parameter indicates that the default action
2445: * or value for that parameter should be used.
2446: * <p>
2447: * The first two parameters (<code>before</code> and
2448: * <code>after</code>) specify the number of characters to be used for
2449: * the integer part and decimal part of the result respectively, as
2450: * defined for {@link #format(int,int)}.
2451: * If either of these is -1 (which indicates the default action), the
2452: * number of characters used will be exactly as many as are needed for
2453: * that part.
2454: * <p>
2455: * The remaining parameters control the use of exponential notation
2456: * and rounding. Three (<code>explaces</code>, <code>exdigits</code>,
2457: * and <code>exform</code>) control the exponent part of the result.
2458: * As before, the default action for any of these parameters may be
2459: * selected by using the value -1.
2460: * <p>
2461: * <code>explaces</code> must be a positive number; it sets the number
2462: * of places (digits after the sign of the exponent) to be used for
2463: * any exponent part, the default (when <code>explaces</code> is -1)
2464: * being to use as many as are needed.
2465: * If <code>explaces</code> is not -1, space is always reserved for
2466: * an exponent; if one is not needed (for example, if the exponent
2467: * will be 0) then <code>explaces</code>+2 blanks are appended to the
2468: * result.
2469: * <!-- (This preserves vertical alignment of similarly formatted
2470: * numbers in a monospace font.) -->
2471: * If <code>explaces</code> is not -1 and is not large enough to
2472: * contain the exponent, an exception is thrown.
2473: * <p>
2474: * <code>exdigits</code> sets the trigger point for use of exponential
2475: * notation. If, before any rounding, the number of places needed
2476: * before the decimal point exceeds <code>exdigits</code>, or if the
2477: * absolute value of the result is less than <code>0.000001</code>,
2478: * then exponential form will be used, provided that
2479: * <code>exdigits</code> was specified.
2480: * When <code>exdigits</code> is -1, exponential notation will never
2481: * be used. If 0 is specified for <code>exdigits</code>, exponential
2482: * notation is always used unless the exponent would be 0.
2483: * <p>
2484: * <code>exform</code> sets the form for exponential notation (if
2485: * needed).
2486: * It may be either {@link MathContext#SCIENTIFIC} or
2487: * {@link MathContext#ENGINEERING}.
2488: * If the latter, engineering, form is requested, up to three digits
2489: * (plus sign, if negative) may be needed for the integer part of the
2490: * result (<code>before</code>). Otherwise, only one digit (plus
2491: * sign, if negative) is needed.
2492: * <p>
2493: * Finally, the sixth argument, <code>exround</code>, selects the
2494: * rounding algorithm to be used, and must be one of the values
2495: * indicated by a public constant in the {@link MathContext} class
2496: * whose name starts with <code>ROUND_</code>.
2497: * The default (<code>ROUND_HALF_UP</code>) may also be selected by
2498: * using the value -1, as before.
2499: * <p>
2500: * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be
2501: * used to detect whether non-zero digits are discarded -- if
2502: * <code>exround</code> has this value than if non-zero digits would
2503: * be discarded (rounded) during formatting then an
2504: * <code>ArithmeticException</code> is thrown.
2505: *
2506: * @param before The <code>int</code> specifying the number of places
2507: * before the decimal point.
2508: * Use -1 for 'as many as are needed'.
2509: * @param after The <code>int</code> specifying the number of places
2510: * after the decimal point.
2511: * Use -1 for 'as many as are needed'.
2512: * @param explaces The <code>int</code> specifying the number of places
2513: * to be used for any exponent.
2514: * Use -1 for 'as many as are needed'.
2515: * @param exdigits The <code>int</code> specifying the trigger
2516: * (digits before the decimal point) which if
2517: * exceeded causes exponential notation to be used.
2518: * Use 0 to force exponential notation.
2519: * Use -1 to force plain notation (no exponential
2520: * notation).
2521: * @param exformint The <code>int</code> specifying the form of
2522: * exponential notation to be used
2523: * ({@link MathContext#SCIENTIFIC} or
2524: * {@link MathContext#ENGINEERING}).
2525: * @param exround The <code>int</code> specifying the rounding mode
2526: * to use.
2527: * Use -1 for the default, {@link MathContext#ROUND_HALF_UP}.
2528: * @return A <code>String</code> representing this
2529: * <code>BigDecimal</code>, laid out according to the
2530: * specified parameters
2531: * @throws ArithmeticException if the number cannot be laid out as
2532: * requested.
2533: * @throws IllegalArgumentException if a parameter is out of range.
2534: * @see #toString
2535: * @see #toCharArray
2536: * @stable ICU 2.0
2537: */
2538:
2539: public java.lang.String format(int before, int after, int explaces,
2540: int exdigits, int exformint, int exround) {
2541: com.ibm.icu.math.BigDecimal num;
2542: int mag = 0;
2543: int this after = 0;
2544: int lead = 0;
2545: byte newmant[] = null;
2546: int chop = 0;
2547: int need = 0;
2548: int oldexp = 0;
2549: char a[];
2550: int p = 0;
2551: char newa[] = null;
2552: int i = 0;
2553: int places = 0;
2554:
2555: /* Check arguments */
2556: if ((before < (-1)) | (before == 0))
2557: badarg("format", 1, java.lang.String.valueOf(before));
2558: if (after < (-1))
2559: badarg("format", 2, java.lang.String.valueOf(after));
2560: if ((explaces < (-1)) | (explaces == 0))
2561: badarg("format", 3, java.lang.String.valueOf(explaces));
2562: if (exdigits < (-1))
2563: badarg("format", 4, java.lang.String.valueOf(explaces));
2564: {/*select*/
2565: if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) {
2566: } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) {
2567: } else if (exformint == (-1))
2568: exformint = com.ibm.icu.math.MathContext.SCIENTIFIC;
2569: // note PLAIN isn't allowed
2570: else {
2571: badarg("format", 5, java.lang.String.valueOf(exformint));
2572: }
2573: }
2574: // checking the rounding mode is done by trying to construct a
2575: // MathContext object with that mode; it will fail if bad
2576: if (exround != ROUND_HALF_UP) {
2577: try { // if non-default...
2578: if (exround == (-1))
2579: exround = ROUND_HALF_UP;
2580: else
2581: new com.ibm.icu.math.MathContext(9,
2582: com.ibm.icu.math.MathContext.SCIENTIFIC,
2583: false, exround);
2584: } catch (java.lang.IllegalArgumentException $10) {
2585: badarg("format", 6, java.lang.String.valueOf(exround));
2586: }
2587: }
2588:
2589: num = clone(this ); // make private copy
2590:
2591: /* Here:
2592: num is BigDecimal to format
2593: before is places before point [>0]
2594: after is places after point [>=0]
2595: explaces is exponent places [>0]
2596: exdigits is exponent digits [>=0]
2597: exformint is exponent form [one of two]
2598: exround is rounding mode [one of eight]
2599: 'before' through 'exdigits' are -1 if not specified
2600: */
2601:
2602: /* determine form */
2603: {
2604: setform: do {/*select*/
2605: if (exdigits == (-1))
2606: num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
2607: else if (num.ind == iszero)
2608: num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
2609: else {
2610: // determine whether triggers
2611: mag = num.exp + num.mant.length;
2612: if (mag > exdigits)
2613: num.form = (byte) exformint;
2614: else if (mag < (-5))
2615: num.form = (byte) exformint;
2616: else
2617: num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
2618: }
2619: } while (false);
2620: }/*setform*/
2621:
2622: /* If 'after' was specified then we may need to adjust the
2623: mantissa. This is a little tricky, as we must conform to the
2624: rules of exponential layout if necessary (e.g., we cannot end up
2625: with 10.0 if scientific). */
2626: if (after >= 0) {
2627: setafter: for (;;) {
2628: // calculate the current after-length
2629: {/*select*/
2630: if (num.form == com.ibm.icu.math.MathContext.PLAIN)
2631: this after = (int) -num.exp; // has decimal part
2632: else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC)
2633: this after = num.mant.length - 1;
2634: else { // engineering
2635: lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use
2636: if (lead < 0)
2637: lead = 3 + lead; // negative exponent case
2638: lead++; // number of leading digits
2639: if (lead >= num.mant.length)
2640: this after = 0;
2641: else
2642: this after = num.mant.length - lead;
2643: }
2644: }
2645: if (this after == after)
2646: break setafter; // we're in luck
2647: if (this after < after) { // need added trailing zeros
2648: // [thisafter can be negative]
2649: newmant = extend(num.mant,
2650: (num.mant.length + after) - this after);
2651: num.mant = newmant;
2652: num.exp = num.exp - ((after - this after)); // adjust exponent
2653: if (num.exp < MinExp)
2654: throw new java.lang.ArithmeticException(
2655: "Exponent Overflow:" + " " + num.exp);
2656: break setafter;
2657: }
2658: // We have too many digits after the decimal point; this could
2659: // cause a carry, which could change the mantissa...
2660: // Watch out for implied leading zeros in PLAIN case
2661: chop = this after - after; // digits to lop [is >0]
2662: if (chop > num.mant.length) { // all digits go, no chance of carry
2663: // carry on with zero
2664: num.mant = ZERO.mant;
2665: num.ind = iszero;
2666: num.exp = 0;
2667: continue setafter; // recheck: we may need trailing zeros
2668: }
2669: // we have a digit to inspect from existing mantissa
2670: // round the number as required
2671: need = num.mant.length - chop; // digits to end up with [may be 0]
2672: oldexp = num.exp; // save old exponent
2673: num.round(need, exround);
2674: // if the exponent grew by more than the digits we chopped, then
2675: // we must have had a carry, so will need to recheck the layout
2676: if ((num.exp - oldexp) == chop)
2677: break setafter; // number did not have carry
2678: // mantissa got extended .. so go around and check again
2679: }
2680: }/*setafter*/
2681:
2682: a = num.layout(); // lay out, with exponent if required, etc.
2683:
2684: /* Here we have laid-out number in 'a' */
2685: // now apply 'before' and 'explaces' as needed
2686: if (before > 0) {
2687: // look for '.' or 'E'
2688: {
2689: int $11 = a.length;
2690: p = 0;
2691: p: for (; $11 > 0; $11--, p++) {
2692: if (a[p] == '.')
2693: break p;
2694: if (a[p] == 'E')
2695: break p;
2696: }
2697: }/*p*/
2698: // p is now offset of '.', 'E', or character after end of array
2699: // that is, the current length of before part
2700: if (p > before)
2701: badarg("format", 1, java.lang.String.valueOf(before)); // won't fit
2702: if (p < before) { // need leading blanks
2703: newa = new char[(a.length + before) - p];
2704: {
2705: int $12 = before - p;
2706: i = 0;
2707: i: for (; $12 > 0; $12--, i++) {
2708: newa[i] = ' ';
2709: }
2710: }/*i*/
2711: java.lang.System.arraycopy((java.lang.Object) a, 0,
2712: (java.lang.Object) newa, i, a.length);
2713: a = newa;
2714: }
2715: // [if p=before then it's just the right length]
2716: }
2717:
2718: if (explaces > 0) {
2719: // look for 'E' [cannot be at offset 0]
2720: {
2721: int $13 = a.length - 1;
2722: p = a.length - 1;
2723: p: for (; $13 > 0; $13--, p--) {
2724: if (a[p] == 'E')
2725: break p;
2726: }
2727: }/*p*/
2728: // p is now offset of 'E', or 0
2729: if (p == 0) { // no E part; add trailing blanks
2730: newa = new char[(a.length + explaces) + 2];
2731: java.lang.System.arraycopy((java.lang.Object) a, 0,
2732: (java.lang.Object) newa, 0, a.length);
2733: {
2734: int $14 = explaces + 2;
2735: i = a.length;
2736: i: for (; $14 > 0; $14--, i++) {
2737: newa[i] = ' ';
2738: }
2739: }/*i*/
2740: a = newa;
2741: } else {/* found E */// may need to insert zeros
2742: places = (a.length - p) - 2; // number so far
2743: if (places > explaces)
2744: badarg("format", 3, java.lang.String
2745: .valueOf(explaces));
2746: if (places < explaces) { // need to insert zeros
2747: newa = new char[(a.length + explaces) - places];
2748: java.lang.System.arraycopy((java.lang.Object) a, 0,
2749: (java.lang.Object) newa, 0, p + 2); // through E and sign
2750: {
2751: int $15 = explaces - places;
2752: i = p + 2;
2753: i: for (; $15 > 0; $15--, i++) {
2754: newa[i] = '0';
2755: }
2756: }/*i*/
2757: java.lang.System.arraycopy((java.lang.Object) a,
2758: p + 2, (java.lang.Object) newa, i, places); // remainder of exponent
2759: a = newa;
2760: }
2761: // [if places=explaces then it's just the right length]
2762: }
2763: }
2764: return new java.lang.String(a);
2765: }
2766:
2767: /**
2768: * Returns the hashcode for this <code>BigDecimal</code>.
2769: * This hashcode is suitable for use by the
2770: * <code>java.util.Hashtable</code> class.
2771: * <p>
2772: * Note that two <code>BigDecimal</code> objects are only guaranteed
2773: * to produce the same hashcode if they are exactly equal (that is,
2774: * the <code>String</code> representations of the
2775: * <code>BigDecimal</code> numbers are identical -- they have the same
2776: * characters in the same sequence).
2777: *
2778: * @return An <code>int</code> that is the hashcode for <code>this</code>.
2779: * @stable ICU 2.0
2780: */
2781:
2782: public int hashCode() {
2783: // Maybe calculate ourselves, later. If so, note that there can be
2784: // more than one internal representation for a given toString() result.
2785: return this .toString().hashCode();
2786: }
2787:
2788: /**
2789: * Converts this <code>BigDecimal</code> to an <code>int</code>.
2790: * If the <code>BigDecimal</code> has a non-zero decimal part it is
2791: * discarded. If the <code>BigDecimal</code> is out of the possible
2792: * range for an <code>int</code> (32-bit signed integer) result then
2793: * only the low-order 32 bits are used. (That is, the number may be
2794: * <i>decapitated</i>.) To avoid unexpected errors when these
2795: * conditions occur, use the {@link #intValueExact} method.
2796: *
2797: * @return An <code>int</code> converted from <code>this</code>,
2798: * truncated and decapitated if necessary.
2799: * @stable ICU 2.0
2800: */
2801:
2802: public int intValue() {
2803: return toBigInteger().intValue();
2804: }
2805:
2806: /**
2807: * Converts this <code>BigDecimal</code> to an <code>int</code>.
2808: * If the <code>BigDecimal</code> has a non-zero decimal part or is
2809: * out of the possible range for an <code>int</code> (32-bit signed
2810: * integer) result then an <code>ArithmeticException</code> is thrown.
2811: *
2812: * @return An <code>int</code> equal in value to <code>this</code>.
2813: * @throws ArithmeticException if <code>this</code> has a non-zero
2814: * decimal part, or will not fit in an
2815: * <code>int</code>.
2816: * @stable ICU 2.0
2817: */
2818:
2819: public int intValueExact() {
2820: int lodigit;
2821: int useexp = 0;
2822: int result;
2823: int i = 0;
2824: int topdig = 0;
2825: // This does not use longValueExact() as the latter can be much
2826: // slower.
2827: // intcheck (from pow) relies on this to check decimal part
2828: if (ind == iszero)
2829: return 0; // easy, and quite common
2830: /* test and drop any trailing decimal part */
2831: lodigit = mant.length - 1;
2832: if (exp < 0) {
2833: lodigit = lodigit + exp; // reduces by -(-exp)
2834: /* all decimal places must be 0 */
2835: if ((!(allzero(mant, lodigit + 1))))
2836: throw new java.lang.ArithmeticException(
2837: "Decimal part non-zero:" + " "
2838: + this .toString());
2839: if (lodigit < 0)
2840: return 0; // -1<this<1
2841: useexp = 0;
2842: } else {/* >=0 */
2843: if ((exp + lodigit) > 9) // early exit
2844: throw new java.lang.ArithmeticException(
2845: "Conversion overflow:" + " " + this .toString());
2846: useexp = exp;
2847: }
2848: /* convert the mantissa to binary, inline for speed */
2849: result = 0;
2850: {
2851: int $16 = lodigit + useexp;
2852: i = 0;
2853: i: for (; i <= $16; i++) {
2854: result = result * 10;
2855: if (i <= lodigit)
2856: result = result + mant[i];
2857: }
2858: }/*i*/
2859:
2860: /* Now, if the risky length, check for overflow */
2861: if ((lodigit + useexp) == 9) {
2862: // note we cannot just test for -ve result, as overflow can move a
2863: // zero into the top bit [consider 5555555555]
2864: topdig = result / 1000000000; // get top digit, preserving sign
2865: if (topdig != mant[0]) { // digit must match and be positive
2866: // except in the special case ...
2867: if (result == java.lang.Integer.MIN_VALUE) // looks like the special
2868: if (ind == isneg) // really was negative
2869: if (mant[0] == 2)
2870: return result; // really had top digit 2
2871: throw new java.lang.ArithmeticException(
2872: "Conversion overflow:" + " " + this .toString());
2873: }
2874: }
2875:
2876: /* Looks good */
2877: if (ind == ispos)
2878: return result;
2879: return (int) -result;
2880: }
2881:
2882: /**
2883: * Converts this <code>BigDecimal</code> to a <code>long</code>.
2884: * If the <code>BigDecimal</code> has a non-zero decimal part it is
2885: * discarded. If the <code>BigDecimal</code> is out of the possible
2886: * range for a <code>long</code> (64-bit signed integer) result then
2887: * only the low-order 64 bits are used. (That is, the number may be
2888: * <i>decapitated</i>.) To avoid unexpected errors when these
2889: * conditions occur, use the {@link #longValueExact} method.
2890: *
2891: * @return A <code>long</code> converted from <code>this</code>,
2892: * truncated and decapitated if necessary.
2893: * @stable ICU 2.0
2894: */
2895:
2896: public long longValue() {
2897: return toBigInteger().longValue();
2898: }
2899:
2900: /**
2901: * Converts this <code>BigDecimal</code> to a <code>long</code>.
2902: * If the <code>BigDecimal</code> has a non-zero decimal part or is
2903: * out of the possible range for a <code>long</code> (64-bit signed
2904: * integer) result then an <code>ArithmeticException</code> is thrown.
2905: *
2906: * @return A <code>long</code> equal in value to <code>this</code>.
2907: * @throws ArithmeticException if <code>this</code> has a non-zero
2908: * decimal part, or will not fit in a
2909: * <code>long</code>.
2910: * @stable ICU 2.0
2911: */
2912:
2913: public long longValueExact() {
2914: int lodigit;
2915: int cstart = 0;
2916: int useexp = 0;
2917: long result;
2918: int i = 0;
2919: long topdig = 0;
2920: // Identical to intValueExact except for result=long, and exp>=20 test
2921: if (ind == 0)
2922: return 0; // easy, and quite common
2923: lodigit = mant.length - 1; // last included digit
2924: if (exp < 0) {
2925: lodigit = lodigit + exp; // -(-exp)
2926: /* all decimal places must be 0 */
2927: if (lodigit < 0)
2928: cstart = 0;
2929: else
2930: cstart = lodigit + 1;
2931: if ((!(allzero(mant, cstart))))
2932: throw new java.lang.ArithmeticException(
2933: "Decimal part non-zero:" + " "
2934: + this .toString());
2935: if (lodigit < 0)
2936: return 0; // -1<this<1
2937: useexp = 0;
2938: } else {/* >=0 */
2939: if ((exp + mant.length) > 18) // early exit
2940: throw new java.lang.ArithmeticException(
2941: "Conversion overflow:" + " " + this .toString());
2942: useexp = exp;
2943: }
2944:
2945: /* convert the mantissa to binary, inline for speed */
2946: // note that we could safely use the 'test for wrap to negative'
2947: // algorithm here, but instead we parallel the intValueExact
2948: // algorithm for ease of checking and maintenance.
2949: result = (long) 0;
2950: {
2951: int $17 = lodigit + useexp;
2952: i = 0;
2953: i: for (; i <= $17; i++) {
2954: result = result * 10;
2955: if (i <= lodigit)
2956: result = result + mant[i];
2957: }
2958: }/*i*/
2959:
2960: /* Now, if the risky length, check for overflow */
2961: if ((lodigit + useexp) == 18) {
2962: topdig = result / 1000000000000000000L; // get top digit, preserving sign
2963: if (topdig != mant[0]) { // digit must match and be positive
2964: // except in the special case ...
2965: if (result == java.lang.Long.MIN_VALUE) // looks like the special
2966: if (ind == isneg) // really was negative
2967: if (mant[0] == 9)
2968: return result; // really had top digit 9
2969: throw new java.lang.ArithmeticException(
2970: "Conversion overflow:" + " " + this .toString());
2971: }
2972: }
2973:
2974: /* Looks good */
2975: if (ind == ispos)
2976: return result;
2977: return (long) -result;
2978: }
2979:
2980: /**
2981: * Returns a plain <code>BigDecimal</code> whose decimal point has
2982: * been moved to the left by a specified number of positions.
2983: * The parameter, <code>n</code>, specifies the number of positions to
2984: * move the decimal point.
2985: * That is, if <code>n</code> is 0 or positive, the number returned is
2986: * given by:
2987: * <p><code>
2988: * this.multiply(TEN.pow(new BigDecimal(-n)))
2989: * </code>
2990: * <p>
2991: * <code>n</code> may be negative, in which case the method returns
2992: * the same result as <code>movePointRight(-n)</code>.
2993: *
2994: * @param n The <code>int</code> specifying the number of places to
2995: * move the decimal point leftwards.
2996: * @return A <code>BigDecimal</code> derived from
2997: * <code>this</code>, with the decimal point moved
2998: * <code>n</code> places to the left.
2999: * @stable ICU 2.0
3000: */
3001:
3002: public com.ibm.icu.math.BigDecimal movePointLeft(int n) {
3003: com.ibm.icu.math.BigDecimal res;
3004: // very little point in optimizing for shift of 0
3005: res = clone(this );
3006: res.exp = res.exp - n;
3007: return res.finish(plainMC, false); // finish sets form and checks exponent
3008: }
3009:
3010: /**
3011: * Returns a plain <code>BigDecimal</code> whose decimal point has
3012: * been moved to the right by a specified number of positions.
3013: * The parameter, <code>n</code>, specifies the number of positions to
3014: * move the decimal point.
3015: * That is, if <code>n</code> is 0 or positive, the number returned is
3016: * given by:
3017: * <p><code>
3018: * this.multiply(TEN.pow(new BigDecimal(n)))
3019: * </code>
3020: * <p>
3021: * <code>n</code> may be negative, in which case the method returns
3022: * the same result as <code>movePointLeft(-n)</code>.
3023: *
3024: * @param n The <code>int</code> specifying the number of places to
3025: * move the decimal point rightwards.
3026: * @return A <code>BigDecimal</code> derived from
3027: * <code>this</code>, with the decimal point moved
3028: * <code>n</code> places to the right.
3029: * @stable ICU 2.0
3030: */
3031:
3032: public com.ibm.icu.math.BigDecimal movePointRight(int n) {
3033: com.ibm.icu.math.BigDecimal res;
3034: res = clone(this );
3035: res.exp = res.exp + n;
3036: return res.finish(plainMC, false);
3037: }
3038:
3039: /**
3040: * Returns the scale of this <code>BigDecimal</code>.
3041: * Returns a non-negative <code>int</code> which is the scale of the
3042: * number. The scale is the number of digits in the decimal part of
3043: * the number if the number were formatted without exponential
3044: * notation.
3045: *
3046: * @return An <code>int</code> whose value is the scale of this
3047: * <code>BigDecimal</code>.
3048: * @stable ICU 2.0
3049: */
3050:
3051: public int scale() {
3052: if (exp >= 0)
3053: return 0; // scale can never be negative
3054: return (int) -exp;
3055: }
3056:
3057: /**
3058: * Returns a plain <code>BigDecimal</code> with a given scale.
3059: * <p>
3060: * If the given scale (which must be zero or positive) is the same as
3061: * or greater than the length of the decimal part (the scale) of this
3062: * <code>BigDecimal</code> then trailing zeros will be added to the
3063: * decimal part as necessary.
3064: * <p>
3065: * If the given scale is less than the length of the decimal part (the
3066: * scale) of this <code>BigDecimal</code> then trailing digits
3067: * will be removed, and in this case an
3068: * <code>ArithmeticException</code> is thrown if any discarded digits
3069: * are non-zero.
3070: * <p>
3071: * The same as {@link #setScale(int, int)}, where the first parameter
3072: * is the scale, and the second is
3073: * <code>MathContext.ROUND_UNNECESSARY</code>.
3074: *
3075: * @param scale The <code>int</code> specifying the scale of the
3076: * resulting <code>BigDecimal</code>.
3077: * @return A plain <code>BigDecimal</code> with the given scale.
3078: * @throws ArithmeticException if <code>scale</code> is negative.
3079: * @throws ArithmeticException if reducing scale would discard
3080: * non-zero digits.
3081: * @stable ICU 2.0
3082: */
3083:
3084: public com.ibm.icu.math.BigDecimal setScale(int scale) {
3085: return setScale(scale, ROUND_UNNECESSARY);
3086: }
3087:
3088: /**
3089: * Returns a plain <code>BigDecimal</code> with a given scale.
3090: * <p>
3091: * If the given scale (which must be zero or positive) is the same as
3092: * or greater than the length of the decimal part (the scale) of this
3093: * <code>BigDecimal</code> then trailing zeros will be added to the
3094: * decimal part as necessary.
3095: * <p>
3096: * If the given scale is less than the length of the decimal part (the
3097: * scale) of this <code>BigDecimal</code> then trailing digits
3098: * will be removed, and the rounding mode given by the second
3099: * parameter is used to determine if the remaining digits are
3100: * affected by a carry.
3101: * In this case, an <code>IllegalArgumentException</code> is thrown if
3102: * <code>round</code> is not a valid rounding mode.
3103: * <p>
3104: * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>,
3105: * an <code>ArithmeticException</code> is thrown if any discarded
3106: * digits are non-zero.
3107: *
3108: * @param scale The <code>int</code> specifying the scale of the
3109: * resulting <code>BigDecimal</code>.
3110: * @param round The <code>int</code> rounding mode to be used for
3111: * the division (see the {@link MathContext} class).
3112: * @return A plain <code>BigDecimal</code> with the given scale.
3113: * @throws IllegalArgumentException if <code>round</code> is not a
3114: * valid rounding mode.
3115: * @throws ArithmeticException if <code>scale</code> is negative.
3116: * @throws ArithmeticException if <code>round</code> is
3117: * <code>MathContext.ROUND_UNNECESSARY</code>, and
3118: * reducing scale would discard non-zero digits.
3119: * @stable ICU 2.0
3120: */
3121:
3122: public com.ibm.icu.math.BigDecimal setScale(int scale, int round) {
3123: int ourscale;
3124: com.ibm.icu.math.BigDecimal res;
3125: int padding = 0;
3126: int newlen = 0;
3127: // at present this naughtily only checks the round value if it is
3128: // needed (used), for speed
3129: ourscale = this .scale();
3130: if (ourscale == scale) // already correct scale
3131: if (this .form == com.ibm.icu.math.MathContext.PLAIN) // .. and form
3132: return this ;
3133: res = clone(this ); // need copy
3134: if (ourscale <= scale) { // simply zero-padding/changing form
3135: // if ourscale is 0 we may have lots of 0s to add
3136: if (ourscale == 0)
3137: padding = res.exp + scale;
3138: else
3139: padding = scale - ourscale;
3140: res.mant = extend(res.mant, res.mant.length + padding);
3141: res.exp = (int) -scale; // as requested
3142: } else {/* ourscale>scale: shortening, probably */
3143: if (scale < 0)
3144: throw new java.lang.ArithmeticException(
3145: "Negative scale:" + " " + scale);
3146: // [round() will raise exception if invalid round]
3147: newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK]
3148: res = res.round(newlen, round); // round to required length
3149: // This could have shifted left if round (say) 0.9->1[.0]
3150: // Repair if so by adding a zero and reducing exponent
3151: if (res.exp != ((int) -scale)) {
3152: res.mant = extend(res.mant, res.mant.length + 1);
3153: res.exp = res.exp - 1;
3154: }
3155: }
3156: res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition
3157: return res;
3158: }
3159:
3160: /**
3161: * Converts this <code>BigDecimal</code> to a <code>short</code>.
3162: * If the <code>BigDecimal</code> has a non-zero decimal part or is
3163: * out of the possible range for a <code>short</code> (16-bit signed
3164: * integer) result then an <code>ArithmeticException</code> is thrown.
3165: *
3166: * @return A <code>short</code> equal in value to <code>this</code>.
3167: * @throws ArithmeticException if <code>this</code> has a non-zero
3168: * decimal part, or will not fit in a
3169: * <code>short</code>.
3170: * @stable ICU 2.0
3171: */
3172:
3173: public short shortValueExact() {
3174: int num;
3175: num = this .intValueExact(); // will check decimal part too
3176: if ((num > 32767) | (num < (-32768)))
3177: throw new java.lang.ArithmeticException(
3178: "Conversion overflow:" + " " + this .toString());
3179: return (short) num;
3180: }
3181:
3182: /**
3183: * Returns the sign of this <code>BigDecimal</code>, as an
3184: * <code>int</code>.
3185: * This returns the <i>signum</i> function value that represents the
3186: * sign of this <code>BigDecimal</code>.
3187: * That is, -1 if the <code>BigDecimal</code> is negative, 0 if it is
3188: * numerically equal to zero, or 1 if it is positive.
3189: *
3190: * @return An <code>int</code> which is -1 if the
3191: * <code>BigDecimal</code> is negative, 0 if it is
3192: * numerically equal to zero, or 1 if it is positive.
3193: * @stable ICU 2.0
3194: */
3195:
3196: public int signum() {
3197: return (int) this .ind; // [note this assumes values for ind.]
3198: }
3199:
3200: //#ifndef FOUNDATION
3201: /**
3202: * Converts this <code>BigDecimal</code> to a
3203: * <code>java.math.BigDecimal</code>.
3204: * <p>
3205: * This is an exact conversion; the result is the same as if the
3206: * <code>BigDecimal</code> were formatted as a plain number without
3207: * any rounding or exponent and then the
3208: * <code>java.math.BigDecimal(java.lang.String)</code> constructor
3209: * were used to construct the result.
3210: * <p>
3211: * <i>(Note: this method is provided only in the
3212: * <code>com.ibm.icu.math</code> version of the BigDecimal class.
3213: * It would not be present in a <code>java.math</code> version.)</i>
3214: *
3215: * @return The <code>java.math.BigDecimal</code> equal in value
3216: * to this <code>BigDecimal</code>.
3217: * @stable ICU 2.0
3218: */
3219:
3220: public java.math.BigDecimal toBigDecimal() {
3221: return new java.math.BigDecimal(this .unscaledValue(), this
3222: .scale());
3223: }
3224:
3225: //#endif
3226:
3227: /**
3228: * Converts this <code>BigDecimal</code> to a
3229: * <code>java.math.BigInteger</code>.
3230: * <p>
3231: * Any decimal part is truncated (discarded).
3232: * If an exception is desired should the decimal part be non-zero,
3233: * use {@link #toBigIntegerExact()}.
3234: *
3235: * @return The <code>java.math.BigInteger</code> equal in value
3236: * to the integer part of this <code>BigDecimal</code>.
3237: * @stable ICU 2.0
3238: */
3239:
3240: public java.math.BigInteger toBigInteger() {
3241: com.ibm.icu.math.BigDecimal res = null;
3242: int newlen = 0;
3243: byte newmant[] = null;
3244: {/*select*/
3245: if ((exp >= 0)
3246: & (form == com.ibm.icu.math.MathContext.PLAIN))
3247: res = this ; // can layout simply
3248: else if (exp >= 0) {
3249: res = clone(this ); // safe copy
3250: res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
3251: } else {
3252: { // exp<0; scale to be truncated
3253: // we could use divideInteger, but we may as well be quicker
3254: if (((int) -this .exp) >= this .mant.length)
3255: res = ZERO; // all blows away
3256: else {
3257: res = clone(this ); // safe copy
3258: newlen = res.mant.length + res.exp;
3259: newmant = new byte[newlen]; // [shorter]
3260: java.lang.System.arraycopy(
3261: (java.lang.Object) res.mant, 0,
3262: (java.lang.Object) newmant, 0, newlen);
3263: res.mant = newmant;
3264: res.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
3265: res.exp = 0;
3266: }
3267: }
3268: }
3269: }
3270: return new BigInteger(new java.lang.String(res.layout()));
3271: }
3272:
3273: /**
3274: * Converts this <code>BigDecimal</code> to a
3275: * <code>java.math.BigInteger</code>.
3276: * <p>
3277: * An exception is thrown if the decimal part (if any) is non-zero.
3278: *
3279: * @return The <code>java.math.BigInteger</code> equal in value
3280: * to the integer part of this <code>BigDecimal</code>.
3281: * @throws ArithmeticException if <code>this</code> has a non-zero
3282: * decimal part.
3283: * @stable ICU 2.0
3284: */
3285:
3286: public java.math.BigInteger toBigIntegerExact() {
3287: /* test any trailing decimal part */
3288: if (exp < 0) { // possible decimal part
3289: /* all decimal places must be 0; note exp<0 */
3290: if ((!(allzero(mant, mant.length + exp))))
3291: throw new java.lang.ArithmeticException(
3292: "Decimal part non-zero:" + " "
3293: + this .toString());
3294: }
3295: return toBigInteger();
3296: }
3297:
3298: /**
3299: * Returns the <code>BigDecimal</code> as a character array.
3300: * The result of this method is the same as using the
3301: * sequence <code>toString().toCharArray()</code>, but avoids creating
3302: * the intermediate <code>String</code> and <code>char[]</code>
3303: * objects.
3304: *
3305: * @return The <code>char[]</code> array corresponding to this
3306: * <code>BigDecimal</code>.
3307: * @stable ICU 2.0
3308: */
3309:
3310: public char[] toCharArray() {
3311: return layout();
3312: }
3313:
3314: /**
3315: * Returns the <code>BigDecimal</code> as a <code>String</code>.
3316: * This returns a <code>String</code> that exactly represents this
3317: * <code>BigDecimal</code>, as defined in the decimal documentation
3318: * (see {@link BigDecimal class header}).
3319: * <p>
3320: * By definition, using the {@link #BigDecimal(String)} constructor
3321: * on the result <code>String</code> will create a
3322: * <code>BigDecimal</code> that is exactly equal to the original
3323: * <code>BigDecimal</code>.
3324: *
3325: * @return The <code>String</code> exactly corresponding to this
3326: * <code>BigDecimal</code>.
3327: * @see #format(int, int)
3328: * @see #format(int, int, int, int, int, int)
3329: * @see #toCharArray()
3330: * @stable ICU 2.0
3331: */
3332:
3333: public java.lang.String toString() {
3334: return new java.lang.String(layout());
3335: }
3336:
3337: /**
3338: * Returns the number as a <code>BigInteger</code> after removing the
3339: * scale.
3340: * That is, the number is expressed as a plain number, any decimal
3341: * point is then removed (retaining the digits of any decimal part),
3342: * and the result is then converted to a <code>BigInteger</code>.
3343: *
3344: * @return The <code>java.math.BigInteger</code> equal in value to
3345: * this <code>BigDecimal</code> multiplied by ten to the
3346: * power of <code>this.scale()</code>.
3347: * @stable ICU 2.0
3348: */
3349:
3350: public java.math.BigInteger unscaledValue() {
3351: com.ibm.icu.math.BigDecimal res = null;
3352: if (exp >= 0)
3353: res = this ;
3354: else {
3355: res = clone(this ); // safe copy
3356: res.exp = 0; // drop scale
3357: }
3358: return res.toBigInteger();
3359: }
3360:
3361: /**
3362: * Translates a <code>double</code> to a <code>BigDecimal</code>.
3363: * <p>
3364: * Returns a <code>BigDecimal</code> which is the decimal
3365: * representation of the 64-bit signed binary floating point
3366: * parameter. If the parameter is infinite, or is not a number (NaN),
3367: * a <code>NumberFormatException</code> is thrown.
3368: * <p>
3369: * The number is constructed as though <code>num</code> had been
3370: * converted to a <code>String</code> using the
3371: * <code>Double.toString()</code> method and the
3372: * {@link #BigDecimal(java.lang.String)} constructor had then been used.
3373: * This is typically not an exact conversion.
3374: *
3375: * @param dub The <code>double</code> to be translated.
3376: * @return The <code>BigDecimal</code> equal in value to
3377: * <code>dub</code>.
3378: * @throws NumberFormatException if the parameter is infinite or
3379: * not a number.
3380: * @stable ICU 2.0
3381: */
3382:
3383: public static com.ibm.icu.math.BigDecimal valueOf(double dub) {
3384: // Reminder: a zero double returns '0.0', so we cannot fastpath to
3385: // use the constant ZERO. This might be important enough to justify
3386: // a factory approach, a cache, or a few private constants, later.
3387: return new com.ibm.icu.math.BigDecimal((new java.lang.Double(
3388: dub)).toString());
3389: }
3390:
3391: /**
3392: * Translates a <code>long</code> to a <code>BigDecimal</code>.
3393: * That is, returns a plain <code>BigDecimal</code> whose value is
3394: * equal to the given <code>long</code>.
3395: *
3396: * @param lint The <code>long</code> to be translated.
3397: * @return The <code>BigDecimal</code> equal in value to
3398: * <code>lint</code>.
3399: * @stable ICU 2.0
3400: */
3401:
3402: public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
3403: return valueOf(lint, 0);
3404: }
3405:
3406: /**
3407: * Translates a <code>long</code> to a <code>BigDecimal</code> with a
3408: * given scale.
3409: * That is, returns a plain <code>BigDecimal</code> whose unscaled
3410: * value is equal to the given <code>long</code>, adjusted by the
3411: * second parameter, <code>scale</code>.
3412: * <p>
3413: * The result is given by:
3414: * <p><code>
3415: * (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale)))
3416: * </code>
3417: * <p>
3418: * A <code>NumberFormatException</code> is thrown if <code>scale</code>
3419: * is negative.
3420: *
3421: * @param lint The <code>long</code> to be translated.
3422: * @param scale The <code>int</code> scale to be applied.
3423: * @return The <code>BigDecimal</code> equal in value to
3424: * <code>lint</code>.
3425: * @throws NumberFormatException if the scale is negative.
3426: * @stable ICU 2.0
3427: */
3428:
3429: public static com.ibm.icu.math.BigDecimal valueOf(long lint,
3430: int scale) {
3431: com.ibm.icu.math.BigDecimal res = null;
3432: {/*select*/
3433: if (lint == 0)
3434: res = ZERO;
3435: else if (lint == 1)
3436: res = ONE;
3437: else if (lint == 10)
3438: res = TEN;
3439: else {
3440: res = new com.ibm.icu.math.BigDecimal(lint);
3441: }
3442: }
3443: if (scale == 0)
3444: return res;
3445: if (scale < 0)
3446: throw new java.lang.NumberFormatException("Negative scale:"
3447: + " " + scale);
3448: res = clone(res); // safe copy [do not mutate]
3449: res.exp = (int) -scale; // exponent is -scale
3450: return res;
3451: }
3452:
3453: /* ---------------------------------------------------------------- */
3454: /* Private methods */
3455: /* ---------------------------------------------------------------- */
3456:
3457: /* <sgml> Return char array value of a BigDecimal (conversion from
3458: BigDecimal to laid-out canonical char array).
3459: <p>The mantissa will either already have been rounded (following an
3460: operation) or will be of length appropriate (in the case of
3461: construction from an int, for example).
3462: <p>We must not alter the mantissa, here.
3463: <p>'form' describes whether we are to use exponential notation (and
3464: if so, which), or if we are to lay out as a plain/pure numeric.
3465: </sgml> */
3466:
3467: private char[] layout() {
3468: char cmant[];
3469: int i = 0;
3470: java.lang.StringBuffer sb = null;
3471: int euse = 0;
3472: int sig = 0;
3473: char csign = 0;
3474: char rec[] = null;
3475: int needsign;
3476: int mag;
3477: int len = 0;
3478: cmant = new char[mant.length]; // copy byte[] to a char[]
3479: {
3480: int $18 = mant.length;
3481: i = 0;
3482: i: for (; $18 > 0; $18--, i++) {
3483: cmant[i] = (char) (mant[i] + ((int) ('0')));
3484: }
3485: }/*i*/
3486:
3487: if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */
3488: sb = new java.lang.StringBuffer(cmant.length + 15); // -x.xxxE+999999999
3489: if (ind == isneg)
3490: sb.append('-');
3491: euse = (exp + cmant.length) - 1; // exponent to use
3492: /* setup sig=significant digits and copy to result */
3493: if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default]
3494: sb.append(cmant[0]); // significant character
3495: if (cmant.length > 1) // have decimal part
3496: sb.append('.').append(cmant, 1, cmant.length - 1);
3497: } else {
3498: engineering: do {
3499: sig = euse % 3; // common
3500: if (sig < 0)
3501: sig = 3 + sig; // negative exponent
3502: euse = euse - sig;
3503: sig++;
3504: if (sig >= cmant.length) { // zero padding may be needed
3505: sb.append(cmant, 0, cmant.length);
3506: {
3507: int $19 = sig - cmant.length;
3508: for (; $19 > 0; $19--) {
3509: sb.append('0');
3510: }
3511: }
3512: } else { // decimal point needed
3513: sb.append(cmant, 0, sig).append('.').append(
3514: cmant, sig, cmant.length - sig);
3515: }
3516: } while (false);
3517: }/*engineering*/
3518: if (euse != 0) {
3519: if (euse < 0) {
3520: csign = '-';
3521: euse = (int) -euse;
3522: } else
3523: csign = '+';
3524: sb.append('E').append(csign).append(euse);
3525: }
3526: rec = new char[sb.length()];
3527: Utility.getChars(sb, 0, sb.length(), rec, 0);
3528: return rec;
3529: }
3530:
3531: /* Here for non-exponential (plain) notation */
3532: if (exp == 0) {/* easy */
3533: if (ind >= 0)
3534: return cmant; // non-negative integer
3535: rec = new char[cmant.length + 1];
3536: rec[0] = '-';
3537: java.lang.System.arraycopy((java.lang.Object) cmant, 0,
3538: (java.lang.Object) rec, 1, cmant.length);
3539: return rec;
3540: }
3541:
3542: /* Need a '.' and/or some zeros */
3543: needsign = (int) ((ind == isneg) ? 1 : 0); // space for sign? 0 or 1
3544:
3545: /* MAG is the position of the point in the mantissa (index of the
3546: character it follows) */
3547: mag = exp + cmant.length;
3548:
3549: if (mag < 1) {/* 0.00xxxx form */
3550: len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length
3551: rec = new char[len];
3552: if (needsign != 0)
3553: rec[0] = '-';
3554: rec[needsign] = '0';
3555: rec[needsign + 1] = '.';
3556: {
3557: int $20 = (int) -mag;
3558: i = needsign + 2;
3559: i: for (; $20 > 0; $20--, i++) { // maybe none
3560: rec[i] = '0';
3561: }
3562: }/*i*/
3563: java.lang.System.arraycopy((java.lang.Object) cmant, 0,
3564: (java.lang.Object) rec, (needsign + 2) - mag,
3565: cmant.length);
3566: return rec;
3567: }
3568:
3569: if (mag > cmant.length) {/* xxxx0000 form */
3570: len = needsign + mag;
3571: rec = new char[len];
3572: if (needsign != 0)
3573: rec[0] = '-';
3574: java.lang.System.arraycopy((java.lang.Object) cmant, 0,
3575: (java.lang.Object) rec, needsign, cmant.length);
3576: {
3577: int $21 = mag - cmant.length;
3578: i = needsign + cmant.length;
3579: i: for (; $21 > 0; $21--, i++) { // never 0
3580: rec[i] = '0';
3581: }
3582: }/*i*/
3583: return rec;
3584: }
3585:
3586: /* decimal point is in the middle of the mantissa */
3587: len = (needsign + 1) + cmant.length;
3588: rec = new char[len];
3589: if (needsign != 0)
3590: rec[0] = '-';
3591: java.lang.System.arraycopy((java.lang.Object) cmant, 0,
3592: (java.lang.Object) rec, needsign, mag);
3593: rec[needsign + mag] = '.';
3594: java.lang.System.arraycopy((java.lang.Object) cmant, mag,
3595: (java.lang.Object) rec, (needsign + mag) + 1,
3596: cmant.length - mag);
3597: return rec;
3598: }
3599:
3600: /* <sgml> Checks a BigDecimal argument to ensure it's a true integer
3601: in a given range.
3602: <p>If OK, returns it as an int. </sgml> */
3603: // [currently only used by pow]
3604: private int intcheck(int min, int max) {
3605: int i;
3606: i = this .intValueExact(); // [checks for non-0 decimal part]
3607: // Use same message as though intValueExact failed due to size
3608: if ((i < min) | (i > max))
3609: throw new java.lang.ArithmeticException(
3610: "Conversion overflow:" + " " + i);
3611: return i;
3612: }
3613:
3614: /* <sgml> Carry out division operations. </sgml> */
3615: /*
3616: Arg1 is operation code: D=divide, I=integer divide, R=remainder
3617: Arg2 is the rhs.
3618: Arg3 is the context.
3619: Arg4 is explicit scale iff code='D' or 'I' (-1 if none).
3620:
3621: Underlying algorithm (complications for Remainder function and
3622: scaled division are omitted for clarity):
3623:
3624: Test for x/0 and then 0/x
3625: Exp =Exp1 - Exp2
3626: Exp =Exp +len(var1) -len(var2)
3627: Sign=Sign1 * Sign2
3628: Pad accumulator (Var1) to double-length with 0's (pad1)
3629: Pad Var2 to same length as Var1
3630: B2B=1st two digits of var2, +1 to allow for roundup
3631: have=0
3632: Do until (have=digits+1 OR residue=0)
3633: if exp<0 then if integer divide/residue then leave
3634: this_digit=0
3635: Do forever
3636: compare numbers
3637: if <0 then leave inner_loop
3638: if =0 then (- quick exit without subtract -) do
3639: this_digit=this_digit+1; output this_digit
3640: leave outer_loop; end
3641: Compare lengths of numbers (mantissae):
3642: If same then CA=first_digit_of_Var1
3643: else CA=first_two_digits_of_Var1
3644: mult=ca*10/b2b -- Good and safe guess at divisor
3645: if mult=0 then mult=1
3646: this_digit=this_digit+mult
3647: subtract
3648: end inner_loop
3649: if have\=0 | this_digit\=0 then do
3650: output this_digit
3651: have=have+1; end
3652: var2=var2/10
3653: exp=exp-1
3654: end outer_loop
3655: exp=exp+1 -- set the proper exponent
3656: if have=0 then generate answer=0
3657: Return to FINISHED
3658: Result defined by MATHV1
3659:
3660: For extended commentary, see DMSRCN.
3661: */
3662:
3663: private com.ibm.icu.math.BigDecimal dodivide(char code,
3664: com.ibm.icu.math.BigDecimal rhs,
3665: com.ibm.icu.math.MathContext set, int scale) {
3666: com.ibm.icu.math.BigDecimal lhs;
3667: int reqdig;
3668: int newexp;
3669: com.ibm.icu.math.BigDecimal res;
3670: int newlen;
3671: byte var1[];
3672: int var1len;
3673: byte var2[];
3674: int var2len;
3675: int b2b;
3676: int have;
3677: int this digit = 0;
3678: int i = 0;
3679: byte v2 = 0;
3680: int ba = 0;
3681: int mult = 0;
3682: int start = 0;
3683: int padding = 0;
3684: int d = 0;
3685: byte newvar1[] = null;
3686: byte lasthave = 0;
3687: int actdig = 0;
3688: byte newmant[] = null;
3689:
3690: if (set.lostDigits)
3691: checkdigits(rhs, set.digits);
3692: lhs = this ; // name for clarity
3693:
3694: // [note we must have checked lostDigits before the following checks]
3695: if (rhs.ind == 0)
3696: throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
3697: if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s]
3698: if (set.form != com.ibm.icu.math.MathContext.PLAIN)
3699: return ZERO;
3700: if (scale == (-1))
3701: return lhs;
3702: return lhs.setScale(scale);
3703: }
3704:
3705: /* Prepare numbers according to BigDecimal rules */
3706: reqdig = set.digits; // local copy (heavily used)
3707: if (reqdig > 0) {
3708: if (lhs.mant.length > reqdig)
3709: lhs = clone(lhs).round(set);
3710: if (rhs.mant.length > reqdig)
3711: rhs = clone(rhs).round(set);
3712: } else {/* scaled divide */
3713: if (scale == (-1))
3714: scale = lhs.scale();
3715: // set reqdig to be at least large enough for the computation
3716: reqdig = lhs.mant.length; // base length
3717: // next line handles both positive lhs.exp and also scale mismatch
3718: if (scale != ((int) -lhs.exp))
3719: reqdig = (reqdig + scale) + lhs.exp;
3720: reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect
3721: if (reqdig < lhs.mant.length)
3722: reqdig = lhs.mant.length; // clamp
3723: if (reqdig < rhs.mant.length)
3724: reqdig = rhs.mant.length; // ..
3725: }
3726:
3727: /* precalculate exponent */
3728: newexp = ((lhs.exp - rhs.exp) + lhs.mant.length)
3729: - rhs.mant.length;
3730: /* If new exponent -ve, then some quick exits are possible */
3731: if (newexp < 0)
3732: if (code != 'D') {
3733: if (code == 'I')
3734: return ZERO; // easy - no integer part
3735: /* Must be 'R'; remainder is [finished clone of] input value */
3736: return clone(lhs).finish(set, false);
3737: }
3738:
3739: /* We need slow division */
3740: res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
3741: res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I)
3742: res.exp = newexp; // initial exponent (for D/I)
3743: res.mant = new byte[reqdig + 1]; // where build the result
3744:
3745: /* Now [virtually pad the mantissae with trailing zeros */
3746: // Also copy the LHS, which will be our working array
3747: newlen = (reqdig + reqdig) + 1;
3748: var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array
3749: var1len = newlen; // [remaining digits are 0]
3750:
3751: var2 = rhs.mant;
3752: var2len = newlen;
3753:
3754: /* Calculate first two digits of rhs (var2), +1 for later estimations */
3755: b2b = (var2[0] * 10) + 1;
3756: if (var2.length > 1)
3757: b2b = b2b + var2[1];
3758:
3759: /* start the long-division loops */
3760: have = 0;
3761: {
3762: outer: for (;;) {
3763: this digit = 0;
3764: /* find the next digit */
3765: {
3766: inner: for (;;) {
3767: if (var1len < var2len)
3768: break inner; // V1 too low
3769: if (var1len == var2len) { // compare needed
3770: {
3771: compare: do { // comparison
3772: {
3773: int $22 = var1len;
3774: i = 0;
3775: i: for (; $22 > 0; $22--, i++) {
3776: // var1len is always <= var1.length
3777: if (i < var2.length)
3778: v2 = var2[i];
3779: else
3780: v2 = (byte) 0;
3781: if (var1[i] < v2)
3782: break inner; // V1 too low
3783: if (var1[i] > v2)
3784: break compare; // OK to subtract
3785: }
3786: }/*i*/
3787: /* reach here if lhs and rhs are identical; subtraction will
3788: increase digit by one, and the residue will be 0 so we
3789: are done; leave the loop with residue set to 0 (in case
3790: code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is
3791: being checked) */
3792: this digit++;
3793: res.mant[have] = (byte) this digit;
3794: have++;
3795: var1[0] = (byte) 0; // residue to 0 [this is all we'll test]
3796: // var1len=1 -- [optimized out]
3797: break outer;
3798: } while (false);
3799: }/*compare*/
3800: /* prepare for subtraction. Estimate BA (lengths the same) */
3801: ba = (int) var1[0]; // use only first digit
3802: } // lengths the same
3803: else {/* lhs longer than rhs */
3804: /* use first two digits for estimate */
3805: ba = var1[0] * 10;
3806: if (var1len > 1)
3807: ba = ba + var1[1];
3808: }
3809: /* subtraction needed; V1>=V2 */
3810: mult = (ba * 10) / b2b;
3811: if (mult == 0)
3812: mult = 1;
3813: this digit = this digit + mult;
3814: // subtract; var1 reusable
3815: var1 = byteaddsub(var1, var1len, var2, var2len,
3816: (int) -mult, true);
3817: if (var1[0] != 0)
3818: continue inner; // maybe another subtract needed
3819: /* V1 now probably has leading zeros, remove leading 0's and try
3820: again. (It could be longer than V2) */
3821: {
3822: int $23 = var1len - 2;
3823: start = 0;
3824: start: for (; start <= $23; start++) {
3825: if (var1[start] != 0)
3826: break start;
3827: var1len--;
3828: }
3829: }/*start*/
3830: if (start == 0)
3831: continue inner;
3832: // shift left
3833: java.lang.System.arraycopy(
3834: (java.lang.Object) var1, start,
3835: (java.lang.Object) var1, 0, var1len);
3836: }
3837: }/*inner*/
3838:
3839: /* We have the next digit */
3840: if ((have != 0) | (this digit != 0)) { // put the digit we got
3841: res.mant[have] = (byte) this digit;
3842: have++;
3843: if (have == (reqdig + 1))
3844: break outer; // we have all we need
3845: if (var1[0] == 0)
3846: break outer; // residue now 0
3847: }
3848: /* can leave now if a scaled divide and exponent is small enough */
3849: if (scale >= 0)
3850: if (((int) -res.exp) > scale)
3851: break outer;
3852: /* can leave now if not Divide and no integer part left */
3853: if (code != 'D')
3854: if (res.exp <= 0)
3855: break outer;
3856: res.exp = res.exp - 1; // reduce the exponent
3857: /* to get here, V1 is less than V2, so divide V2 by 10 and go for
3858: the next digit */
3859: var2len--;
3860: }
3861: }/*outer*/
3862:
3863: /* here when we have finished dividing, for some reason */
3864: // have is the number of digits we collected in res.mant
3865: if (have == 0)
3866: have = 1; // res.mant[0] is 0; we always want a digit
3867:
3868: if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */
3869: if ((have + res.exp) > reqdig)
3870: throw new java.lang.ArithmeticException(
3871: "Integer overflow");
3872:
3873: if (code == 'R') {
3874: remainder: do {
3875: /* We were doing Remainder -- return the residue */
3876: if (res.mant[0] == 0) // no integer part was found
3877: return clone(lhs).finish(set, false); // .. so return lhs, canonical
3878: if (var1[0] == 0)
3879: return ZERO; // simple 0 residue
3880: res.ind = lhs.ind; // sign is always as LHS
3881: /* Calculate the exponent by subtracting the number of padding zeros
3882: we added and adding the original exponent */
3883: padding = ((reqdig + reqdig) + 1) - lhs.mant.length;
3884: res.exp = (res.exp - padding) + lhs.exp;
3885:
3886: /* strip insignificant padding zeros from residue, and create/copy
3887: the resulting mantissa if need be */
3888: d = var1len;
3889: {
3890: i = d - 1;
3891: i: for (; i >= 1; i--) {
3892: if (!((res.exp < lhs.exp) & (res.exp < rhs.exp)))
3893: break;
3894: if (var1[i] != 0)
3895: break i;
3896: d--;
3897: res.exp = res.exp + 1;
3898: }
3899: }/*i*/
3900: if (d < var1.length) {/* need to reduce */
3901: newvar1 = new byte[d];
3902: java.lang.System.arraycopy(
3903: (java.lang.Object) var1, 0,
3904: (java.lang.Object) newvar1, 0, d); // shorten
3905: var1 = newvar1;
3906: }
3907: res.mant = var1;
3908: return res.finish(set, false);
3909: } while (false);
3910: }/*remainder*/
3911: }
3912:
3913: else {/* 'D' -- no overflow check needed */
3914: // If there was a residue then bump the final digit (iff 0 or 5)
3915: // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
3916: // ROUND_UNNECESSARY checks (etc.) later.
3917: // [if we finished early, the residue will be 0]
3918: if (var1[0] != 0) { // residue not 0
3919: lasthave = res.mant[have - 1];
3920: if (((lasthave % 5)) == 0)
3921: res.mant[have - 1] = (byte) (lasthave + 1);
3922: }
3923: }
3924:
3925: /* Here for Divide or Integer Divide */
3926: // handle scaled results first ['I' always scale 0, optional for 'D']
3927: if (scale >= 0) {
3928: scaled: do {
3929: // say 'scale have res.exp len' scale have res.exp res.mant.length
3930: if (have != res.mant.length)
3931: // already padded with 0's, so just adjust exponent
3932: res.exp = res.exp - ((res.mant.length - have));
3933: // calculate number of digits we really want [may be 0]
3934: actdig = res.mant.length - ((((int) -res.exp) - scale));
3935: res.round(actdig, set.roundingMode); // round to desired length
3936: // This could have shifted left if round (say) 0.9->1[.0]
3937: // Repair if so by adding a zero and reducing exponent
3938: if (res.exp != ((int) -scale)) {
3939: res.mant = extend(res.mant, res.mant.length + 1);
3940: res.exp = res.exp - 1;
3941: }
3942: return res.finish(set, true); // [strip if not PLAIN]
3943: } while (false);
3944: }/*scaled*/
3945:
3946: // reach here only if a non-scaled
3947: if (have == res.mant.length) { // got digits+1 digits
3948: res.round(set);
3949: have = reqdig;
3950: } else {/* have<=reqdig */
3951: if (res.mant[0] == 0)
3952: return ZERO; // fastpath
3953: // make the mantissa truly just 'have' long
3954: // [we could let finish do this, during strip, if we adjusted
3955: // the exponent; however, truncation avoids the strip loop]
3956: newmant = new byte[have]; // shorten
3957: java.lang.System.arraycopy((java.lang.Object) res.mant, 0,
3958: (java.lang.Object) newmant, 0, have);
3959: res.mant = newmant;
3960: }
3961: return res.finish(set, true);
3962: }
3963:
3964: /* <sgml> Report a conversion exception. </sgml> */
3965:
3966: private void bad(char s[]) {
3967: throw new java.lang.NumberFormatException("Not a number:" + " "
3968: + java.lang.String.valueOf(s));
3969: }
3970:
3971: /* <sgml> Report a bad argument to a method. </sgml>
3972: Arg1 is method name
3973: Arg2 is argument position
3974: Arg3 is what was found */
3975:
3976: private void badarg(java.lang.String name, int pos,
3977: java.lang.String value) {
3978: throw new java.lang.IllegalArgumentException("Bad argument"
3979: + " " + pos + " " + "to" + " " + name + ":" + " "
3980: + value);
3981: }
3982:
3983: /* <sgml> Extend byte array to given length, padding with 0s. If no
3984: extension is required then return the same array. </sgml>
3985:
3986: Arg1 is the source byte array
3987: Arg2 is the new length (longer)
3988: */
3989:
3990: private static final byte[] extend(byte inarr[], int newlen) {
3991: byte newarr[];
3992: if (inarr.length == newlen)
3993: return inarr;
3994: newarr = new byte[newlen];
3995: java.lang.System.arraycopy((java.lang.Object) inarr, 0,
3996: (java.lang.Object) newarr, 0, inarr.length);
3997: // 0 padding is carried out by the JVM on allocation initialization
3998: return newarr;
3999: }
4000:
4001: /* <sgml> Add or subtract two >=0 integers in byte arrays
4002: <p>This routine performs the calculation:
4003: <pre>
4004: C=A+(B*M)
4005: </pre>
4006: Where M is in the range -9 through +9
4007: <p>
4008: If M<0 then A>=B must be true, so the result is always
4009: non-negative.
4010:
4011: Leading zeros are not removed after a subtraction. The result is
4012: either the same length as the longer of A and B, or 1 longer than
4013: that (if a carry occurred).
4014:
4015: A is not altered unless Arg6 is 1.
4016: B is never altered.
4017:
4018: Arg1 is A
4019: Arg2 is A length to use (if longer than A, pad with 0's)
4020: Arg3 is B
4021: Arg4 is B length to use (if longer than B, pad with 0's)
4022: Arg5 is M, the multiplier
4023: Arg6 is 1 if A can be used to build the result (if it fits)
4024:
4025: This routine is severely performance-critical; *any* change here
4026: must be measured (timed) to assure no performance degradation.
4027: */
4028: // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
4029: // 1997.10.05 -- changed to byte arrays (from char arrays)
4030: // 1998.07.01 -- changed to allow destructive reuse of LHS
4031: // 1998.07.01 -- changed to allow virtual lengths for the arrays
4032: // 1998.12.29 -- use lookaside for digit/carry calculation
4033: // 1999.08.07 -- avoid multiply when mult=1, and make db an int
4034: // 1999.12.22 -- special case m=-1, also drop 0 special case
4035: private static final byte[] byteaddsub(byte a[], int avlen,
4036: byte b[], int bvlen, int m, boolean reuse) {
4037: int alength;
4038: int blength;
4039: int ap;
4040: int bp;
4041: int maxarr;
4042: byte reb[];
4043: boolean quickm;
4044: int digit;
4045: int op = 0;
4046: int dp90 = 0;
4047: byte newarr[];
4048: int i = 0;
4049:
4050: // We'll usually be right if we assume no carry
4051: alength = a.length; // physical lengths
4052: blength = b.length; // ..
4053: ap = avlen - 1; // -> final (rightmost) digit
4054: bp = bvlen - 1; // ..
4055: maxarr = bp;
4056: if (maxarr < ap)
4057: maxarr = ap;
4058: reb = (byte[]) null; // result byte array
4059: if (reuse)
4060: if ((maxarr + 1) == alength)
4061: reb = a; // OK to reuse A
4062: if (reb == null)
4063: reb = new byte[maxarr + 1]; // need new array
4064:
4065: quickm = false; // 1 if no multiply needed
4066: if (m == 1)
4067: quickm = true; // most common
4068: else if (m == (-1))
4069: quickm = true; // also common
4070:
4071: digit = 0; // digit, with carry or borrow
4072: {
4073: op = maxarr;
4074: op: for (; op >= 0; op--) {
4075: if (ap >= 0) {
4076: if (ap < alength)
4077: digit = digit + a[ap]; // within A
4078: ap--;
4079: }
4080: if (bp >= 0) {
4081: if (bp < blength) { // within B
4082: if (quickm) {
4083: if (m > 0)
4084: digit = digit + b[bp]; // most common
4085: else
4086: digit = digit - b[bp]; // also common
4087: } else
4088: digit = digit + (b[bp] * m);
4089: }
4090: bp--;
4091: }
4092: /* result so far (digit) could be -90 through 99 */
4093: if (digit < 10)
4094: if (digit >= 0) {
4095: quick: do { // 0-9
4096: reb[op] = (byte) digit;
4097: digit = 0; // no carry
4098: continue op;
4099: } while (false);
4100: }/*quick*/
4101: dp90 = digit + 90;
4102: reb[op] = bytedig[dp90]; // this digit
4103: digit = bytecar[dp90]; // carry or borrow
4104: }
4105: }/*op*/
4106:
4107: if (digit == 0)
4108: return reb; // no carry
4109: // following line will become an Assert, later
4110: // if digit<0 then signal ArithmeticException("internal.error ["digit"]")
4111:
4112: /* We have carry -- need to make space for the extra digit */
4113: newarr = (byte[]) null;
4114: if (reuse)
4115: if ((maxarr + 2) == a.length)
4116: newarr = a; // OK to reuse A
4117: if (newarr == null)
4118: newarr = new byte[maxarr + 2];
4119: newarr[0] = (byte) digit; // the carried digit ..
4120: // .. and all the rest [use local loop for short numbers]
4121: if (maxarr < 10) {
4122: int $24 = maxarr + 1;
4123: i = 0;
4124: i: for (; $24 > 0; $24--, i++) {
4125: newarr[i + 1] = reb[i];
4126: }
4127: }/*i*/
4128: else
4129: java.lang.System.arraycopy((java.lang.Object) reb, 0,
4130: (java.lang.Object) newarr, 1, maxarr + 1);
4131: return newarr;
4132: }
4133:
4134: /* <sgml> Initializer for digit array properties (lookaside). </sgml>
4135: Returns the digit array, and initializes the carry array. */
4136:
4137: private static final byte[] diginit() {
4138: byte work[];
4139: int op = 0;
4140: int digit = 0;
4141: work = new byte[(90 + 99) + 1];
4142: {
4143: op = 0;
4144: op: for (; op <= (90 + 99); op++) {
4145: digit = op - 90;
4146: if (digit >= 0) {
4147: work[op] = (byte) (digit % 10);
4148: bytecar[op] = (byte) (digit / 10); // calculate carry
4149: continue op;
4150: }
4151: // borrowing...
4152: digit = digit + 100; // yes, this is right [consider -50]
4153: work[op] = (byte) (digit % 10);
4154: bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %]
4155: }
4156: }/*op*/
4157: return work;
4158: }
4159:
4160: /* <sgml> Create a copy of BigDecimal object for local use.
4161: <p>This does NOT make a copy of the mantissa array.
4162: </sgml>
4163: Arg1 is the BigDecimal to clone (non-null)
4164: */
4165:
4166: private static final com.ibm.icu.math.BigDecimal clone(
4167: com.ibm.icu.math.BigDecimal dec) {
4168: com.ibm.icu.math.BigDecimal copy;
4169: copy = new com.ibm.icu.math.BigDecimal();
4170: copy.ind = dec.ind;
4171: copy.exp = dec.exp;
4172: copy.form = dec.form;
4173: copy.mant = dec.mant;
4174: return copy;
4175: }
4176:
4177: /* <sgml> Check one or two numbers for lost digits. </sgml>
4178: Arg1 is RHS (or null, if none)
4179: Arg2 is current DIGITS setting
4180: returns quietly or throws an exception */
4181:
4182: private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) {
4183: if (dig == 0)
4184: return; // don't check if digits=0
4185: // first check lhs...
4186: if (this .mant.length > dig)
4187: if ((!(allzero(this .mant, dig))))
4188: throw new java.lang.ArithmeticException(
4189: "Too many digits:" + " " + this .toString());
4190: if (rhs == null)
4191: return; // monadic
4192: if (rhs.mant.length > dig)
4193: if ((!(allzero(rhs.mant, dig))))
4194: throw new java.lang.ArithmeticException(
4195: "Too many digits:" + " " + rhs.toString());
4196: }
4197:
4198: /* <sgml> Round to specified digits, if necessary. </sgml>
4199: Arg1 is requested MathContext [with length and rounding mode]
4200: returns this, for convenience */
4201:
4202: private com.ibm.icu.math.BigDecimal round(
4203: com.ibm.icu.math.MathContext set) {
4204: return round(set.digits, set.roundingMode);
4205: }
4206:
4207: /* <sgml> Round to specified digits, if necessary.
4208: Arg1 is requested length (digits to round to)
4209: [may be <=0 when called from format, dodivide, etc.]
4210: Arg2 is rounding mode
4211: returns this, for convenience
4212:
4213: ind and exp are adjusted, but not cleared for a mantissa of zero
4214:
4215: The length of the mantissa returned will be Arg1, except when Arg1
4216: is 0, in which case the returned mantissa length will be 1.
4217: </sgml>
4218: */
4219:
4220: private com.ibm.icu.math.BigDecimal round(int len, int mode) {
4221: int adjust;
4222: int sign;
4223: byte oldmant[];
4224: boolean reuse = false;
4225: byte first = 0;
4226: int increment;
4227: byte newmant[] = null;
4228: adjust = mant.length - len;
4229: if (adjust <= 0)
4230: return this ; // nowt to do
4231:
4232: exp = exp + adjust; // exponent of result
4233: sign = (int) ind; // save [assumes -1, 0, 1]
4234: oldmant = mant; // save
4235: if (len > 0) {
4236: // remove the unwanted digits
4237: mant = new byte[len];
4238: java.lang.System.arraycopy((java.lang.Object) oldmant, 0,
4239: (java.lang.Object) mant, 0, len);
4240: reuse = true; // can reuse mantissa
4241: first = oldmant[len]; // first of discarded digits
4242: } else {/* len<=0 */
4243: mant = ZERO.mant;
4244: ind = iszero;
4245: reuse = false; // cannot reuse mantissa
4246: if (len == 0)
4247: first = oldmant[0];
4248: else
4249: first = (byte) 0; // [virtual digit]
4250: }
4251:
4252: // decide rounding adjustment depending on mode, sign, and discarded digits
4253: increment = 0; // bumper
4254: {
4255: modes: do {/*select*/
4256: if (mode == ROUND_HALF_UP) { // default first [most common]
4257: if (first >= 5)
4258: increment = sign;
4259: } else if (mode == ROUND_UNNECESSARY) { // default for setScale()
4260: // discarding any non-zero digits is an error
4261: if ((!(allzero(oldmant, len))))
4262: throw new java.lang.ArithmeticException(
4263: "Rounding necessary");
4264: } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down
4265: if (first > 5)
4266: increment = sign;
4267: else if (first == 5)
4268: if ((!(allzero(oldmant, len + 1))))
4269: increment = sign;
4270: } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even
4271: if (first > 5)
4272: increment = sign;
4273: else if (first == 5) {
4274: if ((!(allzero(oldmant, len + 1))))
4275: increment = sign;
4276: else /* 0.5000 */
4277: if ((((mant[mant.length - 1]) % 2)) == 1)
4278: increment = sign;
4279: }
4280: } else if (mode == ROUND_DOWN) {
4281: // never increment
4282: } else if (mode == ROUND_UP) { // increment if discarded non-zero
4283: if ((!(allzero(oldmant, len))))
4284: increment = sign;
4285: } else if (mode == ROUND_CEILING) { // more positive
4286: if (sign > 0)
4287: if ((!(allzero(oldmant, len))))
4288: increment = sign;
4289: } else if (mode == ROUND_FLOOR) { // more negative
4290: if (sign < 0)
4291: if ((!(allzero(oldmant, len))))
4292: increment = sign;
4293: } else {
4294: throw new java.lang.IllegalArgumentException(
4295: "Bad round value:" + " " + mode);
4296: }
4297: } while (false);
4298: }/*modes*/
4299:
4300: if (increment != 0) {
4301: bump: do {
4302: if (ind == iszero) {
4303: // we must not subtract from 0, but result is trivial anyway
4304: mant = ONE.mant;
4305: ind = (byte) increment;
4306: } else {
4307: // mantissa is non-0; we can safely add or subtract 1
4308: if (ind == isneg)
4309: increment = (int) -increment;
4310: newmant = byteaddsub(mant, mant.length, ONE.mant,
4311: 1, increment, reuse);
4312: if (newmant.length > mant.length) { // had a carry
4313: // drop rightmost digit and raise exponent
4314: exp++;
4315: // mant is already the correct length
4316: java.lang.System
4317: .arraycopy((java.lang.Object) newmant,
4318: 0, (java.lang.Object) mant, 0,
4319: mant.length);
4320: } else
4321: mant = newmant;
4322: }
4323: } while (false);
4324: }/*bump*/
4325: // rounding can increase exponent significantly
4326: if (exp > MaxExp)
4327: throw new java.lang.ArithmeticException(
4328: "Exponent Overflow:" + " " + exp);
4329: return this ;
4330: }
4331:
4332: /* <sgml> Test if rightmost digits are all 0.
4333: Arg1 is a mantissa array to test
4334: Arg2 is the offset of first digit to check
4335: [may be negative; if so, digits to left are 0's]
4336: returns 1 if all the digits starting at Arg2 are 0
4337:
4338: Arg2 may be beyond array bounds, in which case 1 is returned
4339: </sgml> */
4340:
4341: private static final boolean allzero(byte array[], int start) {
4342: int i = 0;
4343: if (start < 0)
4344: start = 0;
4345: {
4346: int $25 = array.length - 1;
4347: i = start;
4348: i: for (; i <= $25; i++) {
4349: if (array[i] != 0)
4350: return false;
4351: }
4352: }/*i*/
4353: return true;
4354: }
4355:
4356: /* <sgml> Carry out final checks and canonicalization
4357: <p>
4358: This finishes off the current number by:
4359: 1. Rounding if necessary (NB: length includes leading zeros)
4360: 2. Stripping trailing zeros (if requested and \PLAIN)
4361: 3. Stripping leading zeros (always)
4362: 4. Selecting exponential notation (if required)
4363: 5. Converting a zero result to just '0' (if \PLAIN)
4364: In practice, these operations overlap and share code.
4365: It always sets form.
4366: </sgml>
4367: Arg1 is requested MathContext (length to round to, trigger, and FORM)
4368: Arg2 is 1 if trailing insignificant zeros should be removed after
4369: round (for division, etc.), provided that set.form isn't PLAIN.
4370: returns this, for convenience
4371: */
4372:
4373: private com.ibm.icu.math.BigDecimal finish(
4374: com.ibm.icu.math.MathContext set, boolean strip) {
4375: int d = 0;
4376: int i = 0;
4377: byte newmant[] = null;
4378: int mag = 0;
4379: int sig = 0;
4380: /* Round if mantissa too long and digits requested */
4381: if (set.digits != 0)
4382: if (this .mant.length > set.digits)
4383: this .round(set);
4384:
4385: /* If strip requested (and standard formatting), remove
4386: insignificant trailing zeros. */
4387: if (strip)
4388: if (set.form != com.ibm.icu.math.MathContext.PLAIN) {
4389: d = this .mant.length;
4390: /* see if we need to drop any trailing zeros */
4391: {
4392: i = d - 1;
4393: i: for (; i >= 1; i--) {
4394: if (this .mant[i] != 0)
4395: break i;
4396: d--;
4397: exp++;
4398: }
4399: }/*i*/
4400: if (d < this .mant.length) {/* need to reduce */
4401: newmant = new byte[d];
4402: java.lang.System.arraycopy(
4403: (java.lang.Object) this .mant, 0,
4404: (java.lang.Object) newmant, 0, d);
4405: this .mant = newmant;
4406: }
4407: }
4408:
4409: form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset
4410:
4411: /* Now check for leading- and all- zeros in mantissa */
4412: {
4413: int $26 = this .mant.length;
4414: i = 0;
4415: i: for (; $26 > 0; $26--, i++) {
4416: if (this .mant[i] != 0) {
4417: // non-0 result; ind will be correct
4418: // remove leading zeros [e.g., after subtract]
4419: if (i > 0) {
4420: delead: do {
4421: newmant = new byte[this .mant.length - i];
4422: java.lang.System.arraycopy(
4423: (java.lang.Object) this .mant, i,
4424: (java.lang.Object) newmant, 0,
4425: this .mant.length - i);
4426: this .mant = newmant;
4427: } while (false);
4428: }/*delead*/
4429: // now determine form if not PLAIN
4430: mag = exp + mant.length;
4431: if (mag > 0) { // most common path
4432: if (mag > set.digits)
4433: if (set.digits != 0)
4434: form = (byte) set.form;
4435: if ((mag - 1) <= MaxExp)
4436: return this ; // no overflow; quick return
4437: } else if (mag < (-5))
4438: form = (byte) set.form;
4439: /* check for overflow */
4440: mag--;
4441: if ((mag < MinExp) | (mag > MaxExp)) {
4442: overflow: do {
4443: // possible reprieve if form is engineering
4444: if (form == com.ibm.icu.math.MathContext.ENGINEERING) {
4445: sig = mag % 3; // leftover
4446: if (sig < 0)
4447: sig = 3 + sig; // negative exponent
4448: mag = mag - sig; // exponent to use
4449: // 1999.06.29: second test here must be MaxExp
4450: if (mag >= MinExp)
4451: if (mag <= MaxExp)
4452: break overflow;
4453: }
4454: throw new java.lang.ArithmeticException(
4455: "Exponent Overflow:" + " " + mag);
4456: } while (false);
4457: }/*overflow*/
4458: return this ;
4459: }
4460: }
4461: }/*i*/
4462:
4463: // Drop through to here only if mantissa is all zeros
4464: ind = iszero;
4465: {/*select*/
4466: if (set.form != com.ibm.icu.math.MathContext.PLAIN)
4467: exp = 0; // standard result; go to '0'
4468: else if (exp > 0)
4469: exp = 0; // +ve exponent also goes to '0'
4470: else {
4471: // a plain number with -ve exponent; preserve and check exponent
4472: if (exp < MinExp)
4473: throw new java.lang.ArithmeticException(
4474: "Exponent Overflow:" + " " + exp);
4475: }
4476: }
4477: mant = ZERO.mant; // canonical mantissa
4478: return this;
4479: }
4480: }
|