// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
package com.ibm.icu.math;

import java.math.BigInteger;

/* ------------------------------------------------------------------ */
/* BigDecimal -- Decimal arithmetic for Java                          */
/* ------------------------------------------------------------------ */
/* Copyright IBM Corporation, 1996-2011.  All Rights Reserved.       */
/*                                                                    */
/* The BigDecimal class provides immutable arbitrary-precision        */
/* floating point (including integer) decimal numbers.                */
/*                                                                    */
/* As the numbers are decimal, there is an exact correspondence       */
/* between an instance of a BigDecimal object and its String          */
/* representation; the BigDecimal class provides direct conversions   */
/* to and from String and character array objects, and well as        */
/* conversions to and from the Java primitive types (which may not    */
/* be exact).                                                         */
/* ------------------------------------------------------------------ */
/* Notes:                                                             */
/*                                                                    */
/* 1. A BigDecimal object is never changed in value once constructed; */
/*    this avoids the need for locking.  Note in particular that the  */
/*    mantissa array may be shared between many BigDecimal objects,   */
/*    so that once exposed it must not be altered.                    */
/*                                                                    */
/* 2. This class looks at MathContext class fields directly (for      */
/*    performance).  It must not and does not change them.            */
/*                                                                    */
/* 3. Exponent checking is delayed until finish(), as we know         */
/*    intermediate calculations cannot cause 31-bit overflow.         */
/*    [This assertion depends on MAX_DIGITS in MathContext.]          */
/*                                                                    */
/* 4. Comments for the public API now follow the javadoc conventions. */
/*    The NetRexx -comments option is used to pass these comments     */
/*    through to the generated Java code (with -format, if desired).  */
/*                                                                    */
/* 5. System.arraycopy is faster than explicit loop as follows        */
/*      Mean length 4:  equal                                         */
/*      Mean length 8:  x2                                            */
/*      Mean length 16: x3                                            */
/*      Mean length 24: x4                                            */
/*    From prior experience, we expect mean length a little below 8,  */
/*    but arraycopy is still the one to use, in general, until later  */
/*    measurements suggest otherwise.                                 */
/*                                                                    */
/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370     */
/*    assembler code implementation of the algorithms below; it is    */
/*    now called IXXRCN and is available with the OS/390 and VM/ESA   */
/*    operating systems.                                              */
/* ------------------------------------------------------------------ */
/* Change History:                                                    */
/* 1997.09.02 Initial version (derived from netrexx.lang classes)     */
/* 1997.09.12 Add lostDigits checking                                 */
/* 1997.10.06 Change mantissa to a byte array                         */
/* 1997.11.22 Rework power [did not prepare arguments, etc.]          */
/* 1997.12.13 multiply did not prepare arguments                      */
/* 1997.12.14 add did not prepare and align arguments correctly       */
/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle      */
/* 1998.05.21 adjust remainder operator finalization                  */
/* 1998.06.04 rework to pass MathContext to finish() and round()      */
/* 1998.06.06 change format to use round(); support rounding modes    */
/* 1998.06.25 rename to BigDecimal and begin merge                    */
/*            zero can now have trailing zeros (i.e., exp\=0)         */
/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger         */
/*                         unscaledValue, valueof                     */
/* 1998.07.01 improve byteaddsub to allow array reuse, etc.           */
/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32]     */
/* 1998.07.07 scaled division  [divide(BigDecimal, int, int)]         */
/* 1998.07.08 setScale, faster equals                                 */
/* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
/* 1998.10.12 change package to com.ibm.icu.math                          */
/* 1998.12.14 power operator no longer rounds RHS [to match ANSI]     */
/*            add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
/* 1998.12.29 improve byteaddsub by using table lookup                */
/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
/* 1999.02.05 cleaner code for BigDecimal(char[])                     */
/* 1999.02.06 add javadoc comments                                    */
/* 1999.02.11 format() changed from 7 to 2 method form                */
/* 1999.03.05 null pointer checking is no longer explicit             */
/* 1999.03.05 simplify; changes from discussion with J. Bloch:        */
/*            null no longer permitted for MathContext; drop boolean, */
/*            byte, char, float, short constructor, deprecate double  */
/*            constructor, no blanks in string constructor, add       */
/*            offset and length version of char[] constructor;        */
/*            add valueOf(double); drop booleanValue, charValue;      */
/*            add ...Exact versions of remaining convertors           */
/* 1999.03.13 add toBigIntegerExact                                   */
/* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic          */
/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits  */
/* 1999.07.03 1.03 lost digits should not be checked if digits=0      */
/* 1999.07.06      lost digits Exception message changed              */
/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic)             */
/* 1999.07.17      improve messages from pow method                   */
/* 1999.08.08      performance tweaks                                 */
/* 1999.08.15      fastpath in multiply                               */
/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555]    */
/* 1999.12.22 1.06 remove multiply fastpath, and improve performance  */
/* 2000.01.01      copyright update [Y2K has arrived]                 */
/* 2000.06.18 1.08 no longer deprecate BigDecimal(double)             */
/* ------------------------------------------------------------------ */

/**
 * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the
 * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format
 * conversions, and hashing.
 * <p>
 * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object
 * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from
 * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java
 * primitive types (which may not be exact) and <code>BigInteger</code>.
 * <p>
 * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number
 * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal
 * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any
 * operation.
 * <p>
 * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also
 * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br>
 * <i>[This URL will change.]</i>
 * 
 * <h3>Operator methods</h3>
 * <p>
 * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the
 * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code>
 * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as
 * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9,
 * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point
 * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>.
 * <p>
 * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this
 * version of each method, the context settings used are <code>digits=0,
 * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with
 * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2.
 * <p>
 * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the
 * current object.
 * <p>
 * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The
 * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being
 * the right-hand operand.
 * <p>
 * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and
 * <code>extra</code> could be written as any of:
 * <p>
 * <code>
 *     award.add(extra)
 * <br>award.add(extra, MathContext.DEFAULT)
 * <br>award.add(extra, acontext)
 * </code>
 * <p>
 * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code>
 * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context
 * settings.
 * <p>
 * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by
 * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal
 * arithmetic documentation (see the URL above), but in summary:
 * <ul>
 * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the
 * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be
 * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br>
 * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code>
 * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled)
 * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code>
 * parameter). <br>
 * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm.
 * <li>
 * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is
 * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part).
 * <li>
 * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast
 * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros
 * in the fractional part of results). <br>
 * So, for example:
 * <p>
 * <code>
 *     new BigDecimal("2.40").add(     new BigDecimal("2"))      =&gt; "4.40"
 * <br>new BigDecimal("2.40").subtract(new BigDecimal("2"))      =&gt; "0.40"
 * <br>new BigDecimal("2.40").multiply(new BigDecimal("2"))      =&gt; "4.80"
 * <br>new BigDecimal("2.40").divide(  new BigDecimal("2"), def) =&gt; "1.2"
 * </code>
 * <p>
 * where the value on the right of the <code>=&gt;</code> would be the result of the operation, expressed as a
 * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code>
 * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If
 * necessary, trailing zeros may be easily removed using division by 1.
 * <li>
 * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of
 * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the
 * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number
 * will be expressed in exponential notation; thus
 * <p>
 * <code>
 *   new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
 * </code>
 * <p>
 * results in <code>1E+12</code> instead of <code>1000000000000</code>, and
 * <p>
 * <code>
 *   new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
 * </code>
 * <p>
 * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>.
 * <p>
 * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting.
 * <eul>
 * <p>
 * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>,
 * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
 * 
 * @see MathContext
 * @author Mike Cowlishaw
 * @stable ICU 2.0
 */

public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> {
    // private static final java.lang.String $0="BigDecimal.nrx";

    /* ----- Constants ----- */
    /* properties constant public */// useful to others
    /**
     * The <code>BigDecimal</code> constant "0".
     * 
     * @see #ONE
     * @see #TEN
     * @stable ICU 2.0
     */
    public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we
                                                                                                      // want the int
                                                                                                      // constructor
    // .. to be able to use this, for speed

    /**
     * The <code>BigDecimal</code> constant "1".
     * 
     * @see #TEN
     * @see #ZERO
     * @stable ICU 2.0
     */
    public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we
                                                                                                     // want the int
                                                                                                     // constructor
    // .. to be able to use this, for speed

    /**
     * The <code>BigDecimal</code> constant "10".
     * 
     * @see #ONE
     * @see #ZERO
     * @stable ICU 2.0
     */
    public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10);

    // the rounding modes (copied here for upwards compatibility)
    /**
     * Rounding mode to round to a more positive number.
     * 
     * @see MathContext#ROUND_CEILING
     * @stable ICU 2.0
     */
    public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING;

    /**
     * Rounding mode to round towards zero.
     * 
     * @see MathContext#ROUND_DOWN
     * @stable ICU 2.0
     */
    public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN;

    /**
     * Rounding mode to round to a more negative number.
     * 
     * @see MathContext#ROUND_FLOOR
     * @stable ICU 2.0
     */
    public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR;

    /**
     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down.
     * 
     * @see MathContext#ROUND_HALF_DOWN
     * @stable ICU 2.0
     */
    public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;

    /**
     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor.
     * 
     * @see MathContext#ROUND_HALF_EVEN
     * @stable ICU 2.0
     */
    public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;

    /**
     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up.
     * 
     * @see MathContext#ROUND_HALF_UP
     * @stable ICU 2.0
     */
    public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP;

    /**
     * Rounding mode to assert that no rounding is necessary.
     * 
     * @see MathContext#ROUND_UNNECESSARY
     * @stable ICU 2.0
     */
    public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;

    /**
     * Rounding mode to round away from zero.
     * 
     * @see MathContext#ROUND_UP
     * @stable ICU 2.0
     */
    public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP;

    /* properties constant private */// locals
    private static final byte ispos = 1; // ind: indicates positive (must be 1)
    private static final byte iszero = 0; // ind: indicates zero (must be 0)
    private static final byte isneg = -1; // ind: indicates negative (must be -1)
    // [later could add NaN, +/- infinity, here]

    private static final int MinExp = -999999999; // minimum exponent allowed
    private static final int MaxExp = 999999999; // maximum exponent allowed
    private static final int MinArg = -999999999; // minimum argument integer
    private static final int MaxArg = 999999999; // maximum argument integer

    private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0,
            com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math

    /* properties constant private unused */// present but not referenced
    // Serialization version
    private static final long serialVersionUID = 8245355804974198832L;

    // private static final java.lang.String
    // copyright=" Copyright (c) IBM Corporation 1996, 2000.  All rights reserved. ";

    /* properties static private */
    // Precalculated constant arrays (used by byteaddsub)
    private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
    private static byte bytedig[] = diginit(); // next digit array

    /* ----- Instance properties [all private and immutable] ----- */
    /* properties private */

    /**
     * The indicator. This may take the values:
     * <ul>
     * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative
     * </ul>
     * 
     * @serial
     */
    private byte ind; // assumed undefined
    // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
    // We only need two bits for this, but use a byte [also permits
    // smooth future extension].

    /**
     * The formatting style. This may take the values:
     * <ul>
     * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li>
     * MathContext.ENGINEERING -- engineering notation required
     * </ul>
     * <p>
     * This property is an optimization; it allows us to defer number layout until it is actually needed as a string,
     * hence avoiding unnecessary formatting.
     * 
     * @serial
     */
    private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
    // We only need two bits for this, at present, but use a byte
    // [again, to allow for smooth future extension]

    /**
     * The value of the mantissa.
     * <p>
     * Once constructed, this may become shared between several BigDecimal objects, so must not be altered.
     * <p>
     * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9.
     * <p>
     * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a
     * plain number, for example, 0.000).
     * 
     * @serial
     */
    private byte mant[]; // assumed null

    /**
     * The exponent.
     * <p>
     * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero.
     * 
     * Note that this property can have a value less than MinExp when the mantissa has more than one digit.
     * 
     * @serial
     */
    private int exp;

    // assumed 0

    /* ---------------------------------------------------------------- */
    /* Constructors */
    /* ---------------------------------------------------------------- */

    /**
     * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>.
     * <p>
     * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using
     * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
     * The parameter must not be <code>null</code>.
     * <p>
     * <i>(Note: this constructor is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class.
     * It would not be present in a <code>java.math</code> version.)</i>
     * 
     * @param bd The <code>BigDecimal</code> to be translated.
     * @stable ICU 2.0
     */

    public BigDecimal(java.math.BigDecimal bd) {
        this(bd.toString());
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code>, with scale 0.
     * <p>
     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
     * with a scale of zero. The value of the <code>BigDecimal</code> is identical to the value of the <code>BigInteger
     * </code>. The parameter must not be <code>null</code>.
     * <p>
     * The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the
     * <code>BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
     * 
     * @param bi The <code>BigInteger</code> to be converted.
     * @stable ICU 2.0
     */

    public BigDecimal(java.math.BigInteger bi) {
        this(bi.toString(10));
        return;
    }

    // exp remains 0

    /**
     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code> and a scale.
     * <p>
     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
     * scaled by the second parameter, which may not be negative. The value of the <code>BigDecimal</code> is the <code>
     * BigInteger</code> divided by ten to the power of the scale. The <code>BigInteger</code> parameter must not be
     * <code>null</code>.
     * <p>
     * The <code>BigDecimal</code> will contain only decimal digits, (with an embedded decimal point followed by <code>
     * scale</code> decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the <code>
     * BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
     * 
     * @param bi The <code>BigInteger</code> to be converted.
     * @param scale The <code>int</code> specifying the scale.
     * @throws NumberFormatException If the scale is negative.
     * @stable ICU 2.0
     */

    public BigDecimal(java.math.BigInteger bi, int scale) {
        this(bi.toString(10));
        if (scale < 0)
            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
        exp = -scale; // exponent is -scale
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object from an array of characters.
     * <p>
     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
     * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be
     * <code>null</code>.
     * <p>
     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
     * already available in character array form.
     * 
     * @param inchars The <code>char[]</code> array containing the number to be converted.
     * @throws NumberFormatException If the parameter is not a valid number.
     * @stable ICU 2.0
     */

    public BigDecimal(char inchars[]) {
        this(inchars, 0, inchars.length);
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object from an array of characters.
     * <p>
     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
     * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
     * The first parameter must not be <code>null</code>, and the subarray must be wholly contained within it.
     * <p>
     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
     * already available within a character array.
     * 
     * @param inchars The <code>char[]</code> array containing the number to be converted.
     * @param offset The <code>int</code> offset into the array of the start of the number to be converted.
     * @param length The <code>int</code> length of the number.
     * @throws NumberFormatException If the parameter is not a valid number for any reason.
     * @stable ICU 2.0
     */

    public BigDecimal(char inchars[], int offset, int length) {
        super();
        boolean exotic;
        boolean hadexp;
        int d;
        int dotoff;
        int last;
        int i = 0;
        char si = 0;
        boolean eneg = false;
        int k = 0;
        int elen = 0;
        int j = 0;
        char sj = 0;
        int dvalue = 0;
        int mag = 0;
        // This is the primary constructor; all incoming strings end up
        // here; it uses explicit (inline) parsing for speed and to avoid
        // generating intermediate (temporary) objects of any kind.
        // 1998.06.25: exponent form built only if E/e in string
        // 1998.06.25: trailing zeros not removed for zero
        // 1999.03.06: no embedded blanks; allow offset and length
        if (length <= 0)
            bad(inchars); // bad conversion (empty string)
        // [bad offset will raise array bounds exception]

        /* Handle and step past sign */
        ind = ispos; // assume positive
        if (inchars[offset] == ('-')) {
            length--;
            if (length == 0)
                bad(inchars); // nothing after sign
            ind = isneg;
            offset++;
        } else if (inchars[offset] == ('+')) {
            length--;
            if (length == 0)
                bad(inchars); // nothing after sign
            offset++;
        }

        /* We're at the start of the number */
        exotic = false; // have extra digits
        hadexp = false; // had explicit exponent
        d = 0; // count of digits found
        dotoff = -1; // offset where dot was found
        last = -1; // last character of mantissa
        {
            int $1 = length;
            i = offset;
            i: for (; $1 > 0; $1--, i++) {
                si = inchars[i];
                if (si >= '0') // test for Arabic digit
                    if (si <= '9') {
                        last = i;
                        d++; // still in mantissa
                        continue i;
                    }
                if (si == '.') { // record and ignore
                    if (dotoff >= 0)
                        bad(inchars); // two dots
                    dotoff = i - offset; // offset into mantissa
                    continue i;
                }
                if (si != 'e')
                    if (si != 'E') { // expect an extra digit
                        if ((!(Character.isDigit(si))))
                            bad(inchars); // not a number
                        // defer the base 10 check until later to avoid extra method call
                        exotic = true; // will need conversion later
                        last = i;
                        d++; // still in mantissa
                        continue i;
                    }
                /* Found 'e' or 'E' -- now process explicit exponent */
                // 1998.07.11: sign no longer required
                if ((i - offset) > (length - 2))
                    bad(inchars); // no room for even one digit
                eneg = false;
                if ((inchars[i + 1]) == ('-')) {
                    eneg = true;
                    k = i + 2;
                } else if ((inchars[i + 1]) == ('+'))
                    k = i + 2;
                else
                    k = i + 1;
                // k is offset of first expected digit
                elen = length - ((k - offset)); // possible number of digits
                if ((elen == 0) | (elen > 9))
                    bad(inchars); // 0 or more than 9 digits
                {
                    int $2 = elen;
                    j = k;
                    for (; $2 > 0; $2--, j++) {
                        sj = inchars[j];
                        if (sj < '0')
                            bad(inchars); // always bad
                        if (sj > '9') { // maybe an exotic digit
                            if ((!(Character.isDigit(sj))))
                                bad(inchars); // not a number
                            dvalue = Character.digit(sj, 10); // check base
                            if (dvalue < 0)
                                bad(inchars); // not base 10
                        } else
                            dvalue = ((int) (sj)) - ((int) ('0'));
                        exp = (exp * 10) + dvalue;
                    }
                }/* j */
                if (eneg)
                    exp = -exp; // was negative
                hadexp = true; // remember we had one
                break i; // we are done
            }
        }/* i */

        /* Here when all inspected */
        if (d == 0)
            bad(inchars); // no mantissa digits
        if (dotoff >= 0)
            exp = (exp + dotoff) - d; // adjust exponent if had dot

        /* strip leading zeros/dot (leave final if all 0's) */
        {
            int $3 = last - 1;
            i = offset;
            i: for (; i <= $3; i++) {
                si = inchars[i];
                if (si == '0') {
                    offset++;
                    dotoff--;
                    d--;
                } else if (si == '.') {
                    offset++; // step past dot
                    dotoff--;
                } else if (si <= '9')
                    break i;/* non-0 */
                else {/* exotic */
                    if ((Character.digit(si, 10)) != 0)
                        break i; // non-0 or bad
                    // is 0 .. strip like '0'
                    offset++;
                    dotoff--;
                    d--;
                }
            }
        }/* i */

        /* Create the mantissa array */
        mant = new byte[d]; // we know the length
        j = offset; // input offset
        if (exotic) {
            do { // slow: check for exotica
                {
                    int $4 = d;
                    i = 0;
                    for (; $4 > 0; $4--, i++) {
                        if (i == dotoff)
                            j++; // at dot
                        sj = inchars[j];
                        if (sj <= '9')
                            mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */
                        else {
                            dvalue = Character.digit(sj, 10);
                            if (dvalue < 0)
                                bad(inchars); // not a number after all
                            mant[i] = (byte) dvalue;
                        }
                        j++;
                    }
                }/* i */
            } while (false);
        }/* exotica */
        else {
            do {
                {
                    int $5 = d;
                    i = 0;
                    for (; $5 > 0; $5--, i++) {
                        if (i == dotoff)
                            j++;
                        mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0')));
                        j++;
                    }
                }/* i */
            } while (false);
        }/* simple */

        /* Looks good. Set the sign indicator and form, as needed. */
        // Trailing zeros are preserved
        // The rule here for form is:
        // If no E-notation, then request plain notation
        // Otherwise act as though add(0,DEFAULT) and request scientific notation
        // [form is already PLAIN]
        if (mant[0] == 0) {
            ind = iszero; // force to show zero
            // negative exponent is significant (e.g., -3 for 0.000) if plain
            if (exp > 0)
                exp = 0; // positive exponent can be ignored
            if (hadexp) { // zero becomes single digit from add
                mant = ZERO.mant;
                exp = 0;
            }
        } else { // non-zero
            // [ind was set earlier]
            // now determine form
            if (hadexp) {
                form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC;
                // 1999.06.29 check for overflow
                mag = (exp + mant.length) - 1; // true exponent in scientific notation
                if ((mag < MinExp) | (mag > MaxExp))
                    bad(inchars);
            }
        }
        // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object directly from a <code>double</code>.
     * <p>
     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
     * floating point parameter.
     * <p>
     * Note that this constructor it an exact conversion; it does not give the same result as converting <code>num
     * </code> to a <code>String</code> using the <code>Double.toString()</code> method and then using the
     * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)}
     * method to construct a <code>BigDecimal</code> from a <code>double</code>.
     * 
     * @param num The <code>double</code> to be converted.
     * @throws NumberFormatException If the parameter is infinite or not a number.
     * @stable ICU 2.0
     */

    public BigDecimal(double num) {
        // 1999.03.06: use exactly the old algorithm
        // 2000.01.01: note that this constructor does give an exact result,
        // so perhaps it should not be deprecated
        // 2000.06.18: no longer deprecated
        this((new java.math.BigDecimal(num)).toString());
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object directly from a <code>int</code>.
     * <p>
     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 32-bit signed binary
     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
     * 
     * @param num The <code>int</code> to be converted.
     * @stable ICU 2.0
     */

    public BigDecimal(int num) {
        super();
        int mun;
        int i = 0;
        // We fastpath commoners
        if (num <= 9)
            if (num >= (-9)) {
                do {
                    // very common single digit case
                    {/* select */
                        if (num == 0) {
                            mant = ZERO.mant;
                            ind = iszero;
                        } else if (num == 1) {
                            mant = ONE.mant;
                            ind = ispos;
                        } else if (num == (-1)) {
                            mant = ONE.mant;
                            ind = isneg;
                        } else {
                            {
                                mant = new byte[1];
                                if (num > 0) {
                                    mant[0] = (byte) num;
                                    ind = ispos;
                                } else { // num<-1
                                    mant[0] = (byte) -num;
                                    ind = isneg;
                                }
                            }
                        }
                    }
                    return;
                } while (false);
            }/* singledigit */

        /* We work on negative numbers so we handle the most negative number */
        if (num > 0) {
            ind = ispos;
            num = -num;
        } else
            ind = isneg;/* negative */// [0 case already handled]
        // [it is quicker, here, to pre-calculate the length with
        // one loop, then allocate exactly the right length of byte array,
        // then re-fill it with another loop]
        mun = num; // working copy
        {
            i = 9;
            i: for (;; i--) {
                mun = mun / 10;
                if (mun == 0)
                    break i;
            }
        }/* i */
        // i is the position of the leftmost digit placed
        mant = new byte[10 - i];
        {
            i = (10 - i) - 1;
            i: for (;; i--) {
                mant[i] = (byte) -(((byte) (num % 10)));
                num = num / 10;
                if (num == 0)
                    break i;
            }
        }/* i */
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object directly from a <code>long</code>.
     * <p>
     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
     * 
     * @param num The <code>long</code> to be converted.
     * @stable ICU 2.0
     */

    public BigDecimal(long num) {
        super();
        long mun;
        int i = 0;
        // Not really worth fastpathing commoners in this constructor [also,
        // we use this to construct the static constants].
        // This is much faster than: this(String.valueOf(num).toCharArray())
        /* We work on negative num so we handle the most negative number */
        if (num > 0) {
            ind = ispos;
            num = -num;
        } else if (num == 0)
            ind = iszero;
        else
            ind = isneg;/* negative */
        mun = num;
        {
            i = 18;
            i: for (;; i--) {
                mun = mun / 10;
                if (mun == 0)
                    break i;
            }
        }/* i */
        // i is the position of the leftmost digit placed
        mant = new byte[19 - i];
        {
            i = (19 - i) - 1;
            i: for (;; i--) {
                mant[i] = (byte) -(((byte) (num % 10)));
                num = num / 10;
                if (num == 0)
                    break i;
            }
        }/* i */
        return;
    }

    /**
     * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
     * <p>
     * Constructs a <code>BigDecimal</code> from the parameter, which must not be <code>null</code> and must represent a
     * valid <i>number</i>, as described formally in the documentation referred to {@link BigDecimal above}.
     * <p>
     * In summary, numbers in <code>String</code> form must have at least one digit, may have a leading sign, may have a
     * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks.
     * <p>
     * Some valid strings from which a <code>BigDecimal</code> might be constructed are:
     * 
     * <pre>
     * 
     * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
     * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
     * Exponential notation
     * 
     * </pre>
     * <p>
     * (Exponential notation means that the number includes an optional sign and a power of ten following an
     * '</code>E</code>' that indicates how the decimal point will be shifted. Thus the <code>"4E+9"</code> above is
     * just a short way of writing <code>4000000000</code>, and the <code>"0.73e-7"</code> is short for <code>
     * 0.000000073</code>.)
     * <p>
     * The <code>BigDecimal</code> constructed from the String is in a standard form, with no blanks, as though the
     * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string
     * uses exponential notation (that is, includes an <code>e</code> or an <code>E</code>), then the <code>BigDecimal
     * </code> number will be expressed in scientific notation (where the power of ten is adjusted so there is a single
     * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as
     * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must
     * fit in nine digits both before and after it is expressed in scientific notation.
     * <p>
     * Any digits in the parameter must be decimal; that is, <code>Character.digit(c, 10)</code> (where </code>c</code>
     * is the character in question) would not return -1.
     * 
     * @param string The <code>String</code> to be converted.
     * @throws NumberFormatException If the parameter is not a valid number.
     * @stable ICU 2.0
     */

    public BigDecimal(java.lang.String string) {
        this(string.toCharArray(), 0, string.length());
        return;
    }

    /* <sgml> Make a default BigDecimal object for local use. </sgml> */

    private BigDecimal() {
        super();
        return;
    }

    /* ---------------------------------------------------------------- */
    /* Operator methods [methods which take a context parameter] */
    /* ---------------------------------------------------------------- */

    /**
     * Returns a plain <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
     * <p>
     * The same as {@link #abs(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be <code>this.scale()</code>
     * 
     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal abs() {
        return this.abs(plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
     * <p>
     * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method
     * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)}
     * method with the same parameter is returned.
     * 
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) {
        if (this.ind == isneg)
            return this.negate(set);
        return this.plus(set);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
     * <p>
     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) {
        return this.add(rhs, plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
     * <p>
     * Implements the addition (<b><code>+</code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        com.ibm.icu.math.BigDecimal lhs;
        int reqdig;
        com.ibm.icu.math.BigDecimal res;
        byte usel[];
        int usellen;
        byte user[];
        int userlen;
        int newlen = 0;
        int tlen = 0;
        int mult = 0;
        byte t[] = null;
        int ia = 0;
        int ib = 0;
        int ea = 0;
        int eb = 0;
        byte ca = 0;
        byte cb = 0;
        /* determine requested digits and form */
        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        lhs = this; // name for clarity and proxy

        /* Quick exit for add floating 0 */
        // plus() will optimize to return same object if possible
        if (lhs.ind == 0)
            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
                return rhs.plus(set);
        if (rhs.ind == 0)
            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
                return lhs.plus(set);

        /* Prepare numbers (round, unless unlimited precision) */
        reqdig = set.digits; // local copy (heavily used)
        if (reqdig > 0) {
            if (lhs.mant.length > reqdig)
                lhs = clone(lhs).round(set);
            if (rhs.mant.length > reqdig)
                rhs = clone(rhs).round(set);
            // [we could reuse the new LHS for result in this case]
        }

        res = new com.ibm.icu.math.BigDecimal(); // build result here

        /*
         * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much
         * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to
         * DIGITS trailing zeros].
         */
        // Note sign may be 0 if digits (reqdig) is 0
        // usel and user will be the byte arrays passed to the adder; we'll
        // use them on all paths except quick exits
        usel = lhs.mant;
        usellen = lhs.mant.length;
        user = rhs.mant;
        userlen = rhs.mant.length;
        {
            do {/* select */
                if (lhs.exp == rhs.exp) {/* no padding needed */
                    // This is the most common, and fastest, path
                    res.exp = lhs.exp;
                } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs
                    newlen = (usellen + lhs.exp) - rhs.exp;
                    /*
                     * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot
                     * affect answer, so we only need to pad up to a length of DIGITS+1.
                     */
                    if (newlen >= ((userlen + reqdig) + 1))
                        if (reqdig > 0) {
                            // LHS is sufficient
                            res.mant = usel;
                            res.exp = lhs.exp;
                            res.ind = lhs.ind;
                            if (usellen < reqdig) { // need 0 padding
                                res.mant = extend(lhs.mant, reqdig);
                                res.exp = res.exp - ((reqdig - usellen));
                            }
                            return res.finish(set, false);
                        }
                    // RHS may affect result
                    res.exp = rhs.exp; // expected final exponent
                    if (newlen > (reqdig + 1))
                        if (reqdig > 0) {
                            // LHS will be max; RHS truncated
                            tlen = (newlen - reqdig) - 1; // truncation length
                            userlen = userlen - tlen;
                            res.exp = res.exp + tlen;
                            newlen = reqdig + 1;
                        }
                    if (newlen > usellen)
                        usellen = newlen; // need to pad LHS
                } else { // need to pad rhs and/or truncate lhs
                    newlen = (userlen + rhs.exp) - lhs.exp;
                    if (newlen >= ((usellen + reqdig) + 1))
                        if (reqdig > 0) {
                            // RHS is sufficient
                            res.mant = user;
                            res.exp = rhs.exp;
                            res.ind = rhs.ind;
                            if (userlen < reqdig) { // need 0 padding
                                res.mant = extend(rhs.mant, reqdig);
                                res.exp = res.exp - ((reqdig - userlen));
                            }
                            return res.finish(set, false);
                        }
                    // LHS may affect result
                    res.exp = lhs.exp; // expected final exponent
                    if (newlen > (reqdig + 1))
                        if (reqdig > 0) {
                            // RHS will be max; LHS truncated
                            tlen = (newlen - reqdig) - 1; // truncation length
                            usellen = usellen - tlen;
                            res.exp = res.exp + tlen;
                            newlen = reqdig + 1;
                        }
                    if (newlen > userlen)
                        userlen = newlen; // need to pad RHS
                }
            } while (false);
        }/* padder */

        /* OK, we have aligned mantissas. Now add or subtract. */
        // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
        // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
        // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
        if (lhs.ind == iszero)
            res.ind = ispos;
        else
            res.ind = lhs.ind; // likely sign, all paths
        if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative
            mult = 1;
        else {
            do { // different signs, so subtraction is needed
                mult = -1; // will cause subtract
                /*
                 * Before we can subtract we must determine which is the larger, as our add/subtract routine only
                 * handles non-negative results so we may need to swap the operands.
                 */
                {
                    do {/* select */
                        if (rhs.ind == iszero) {
                            // original A bigger
                        } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger
                            t = usel;
                            usel = user;
                            user = t; // swap
                            tlen = usellen;
                            usellen = userlen;
                            userlen = tlen; // ..
                            res.ind = (byte) -res.ind; // and set sign
                        } else if (usellen > userlen) {
                            // original A bigger
                        } else {
                            {/* logical lengths the same */// need compare
                                /* may still need to swap: compare the strings */
                                ia = 0;
                                ib = 0;
                                ea = usel.length - 1;
                                eb = user.length - 1;
                                {
                                    compare: for (;;) {
                                        if (ia <= ea)
                                            ca = usel[ia];
                                        else {
                                            if (ib > eb) {/* identical */
                                                if (set.form != com.ibm.icu.math.MathContext.PLAIN)
                                                    return ZERO;
                                                // [if PLAIN we must do the subtract, in case of 0.000 results]
                                                break compare;
                                            }
                                            ca = (byte) 0;
                                        }
                                        if (ib <= eb)
                                            cb = user[ib];
                                        else
                                            cb = (byte) 0;
                                        if (ca != cb) {
                                            if (ca < cb) {/* swap needed */
                                                t = usel;
                                                usel = user;
                                                user = t; // swap
                                                tlen = usellen;
                                                usellen = userlen;
                                                userlen = tlen; // ..
                                                res.ind = (byte) -res.ind;
                                            }
                                            break compare;
                                        }
                                        /* mantissas the same, so far */
                                        ia++;
                                        ib++;
                                    }
                                }/* compare */
                            } // lengths the same
                        }
                    } while (false);
                }/* swaptest */
            } while (false);
        }/* signdiff */

        /* here, A is > B if subtracting */
        // add [A+B*1] or subtract [A+(B*-1)]
        res.mant = byteaddsub(usel, usellen, user, userlen, mult, false);
        // [reuse possible only after chop; accounting makes not worthwhile]

        // Finish() rounds before stripping leading 0's, then sets form, etc.
        return res.finish(set, false);
    }

    /**
     * Compares this <code>BigDecimal</code> to another, using unlimited precision.
     * <p>
     * The same as {@link #compareTo(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
     *         or greater than <code>rhs</code>.
     * @stable ICU 2.0
     */

    public int compareTo(com.ibm.icu.math.BigDecimal rhs) {
        return this.compareTo(rhs, plainMC);
    }

    /**
     * Compares this <code>BigDecimal</code> to another.
     * <p>
     * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}),
     * and returns a result of type <code>int</code>.
     * <p>
     * The result will be:
     * <table cellpadding=2>
     * <tr>
     * <td align=right><b>-1</b></td> <td>if the current object is less than the first parameter</td>
     * </tr>
     * <tr>
     * <td align=right><b>0</b></td> <td>if the current object is equal to the first parameter</td>
     * </tr>
     * <tr>
     * <td align=right><b>1</b></td> <td>if the current object is greater than the first parameter.</td>
     * </tr>
     * </table>
     * <p>
     * A {@link #compareTo(BigDecimal)} method is also provided.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
     *         or greater than <code>rhs</code>.
     * @stable ICU 2.0
     */

    public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        int thislength = 0;
        int i = 0;
        com.ibm.icu.math.BigDecimal newrhs;
        // rhs=null will raise NullPointerException, as per Comparable interface
        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        // [add will recheck in slowpath cases .. but would report -rhs]
        if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) {
            /* sign & exponent the same [very common] */
            thislength = this.mant.length;
            if (thislength < rhs.mant.length)
                return (byte) -this.ind;
            if (thislength > rhs.mant.length)
                return this.ind;
            /*
             * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very
             * unusual]
             */
            if ((thislength <= set.digits) | (set.digits == 0)) {
                {
                    int $6 = thislength;
                    i = 0;
                    for (; $6 > 0; $6--, i++) {
                        if (this.mant[i] < rhs.mant[i])
                            return (byte) -this.ind;
                        if (this.mant[i] > rhs.mant[i])
                            return this.ind;
                    }
                }/* i */
                return 0; // identical
            }
            /* drop through for full comparison */
        } else {
            /* More fastpaths possible */
            if (this.ind < rhs.ind)
                return -1;
            if (this.ind > rhs.ind)
                return 1;
        }
        /* carry out a subtract to make the comparison */
        newrhs = clone(rhs); // safe copy
        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
        return this.add(newrhs, set).ind; // add, and return sign of result
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
     * <p>
     * The same as {@link #divide(BigDecimal, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * rounding mode is {@link MathContext#ROUND_HALF_UP}.
     * 
     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
     * the latter were formatted without exponential notation.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
     * @throws ArithmeticException If <code>rhs</code> is zero.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) {
        return this.dodivide('D', rhs, plainMC, -1);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
     * rounding mode.
     * <p>
     * The same as {@link #divide(BigDecimal, int, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * second parameter is <code>this.scale()</code>, and the third is <code>round</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current
     * object, if the latter were formatted without exponential notation.
     * <p>
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
     *         the specified rounding mode.
     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>this.scale()</code> is insufficient to represent the result exactly.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) {
        com.ibm.icu.math.MathContext set;
        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round,
                                                                                                     // too]
        return this.dodivide('D', rhs, set, -1); // take scale from LHS
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
     * given scale and rounding mode.
     * <p>
     * The same as {@link #divide(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
     * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>, except that the length of the decimal part (the
     * scale) to be used for the result is explicit rather than being taken from <code>this</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
     * the latter were formatted without exponential notation.
     * <p>
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
     * @param scale The <code>int</code> scale to be used for the result.
     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
     *         the specified rounding mode.
     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @throws ArithmeticException if <code>scale</code> is negative.
     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>scale</code> is insufficient
     *             to represent the result exactly.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) {
        com.ibm.icu.math.MathContext set;
        if (scale < 0)
            throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round]
        return this.dodivide('D', rhs, set, scale);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
     * <p>
     * Implements the division (<b><code>/</code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>this/rhs</code>.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        return this.dodivide('D', rhs, set, -1);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
     * <p>
     * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs
     * </code>, and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) {
        // scale 0 to drop .000 when plain
        return this.dodivide('I', rhs, plainMC, 0);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
     * <p>
     * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class
     * header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @throws ArithmeticException if the result will not fit in the number of digits specified for the context.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        // scale 0 to drop .000 when plain
        return this.dodivide('I', rhs, set, 0);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
     * <p>
     * The same as {@link #max(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) {
        return this.max(rhs, plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
     * <p>
     * Returns the larger of the current object and the first parameter.
     * <p>
     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>1
     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
     * parameter) is returned.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        if ((this.compareTo(rhs, set)) >= 0)
            return this.plus(set);
        else
            return rhs.plus(set);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
     * <p>
     * The same as {@link #min(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) {
        return this.min(rhs, plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
     * <p>
     * Returns the smaller of the current object and the first parameter.
     * <p>
     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>-1
     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
     * parameter) is returned.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        if ((this.compareTo(rhs, set)) <= 0)
            return this.plus(set);
        else
            return rhs.plus(set);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
     * <p>
     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they
     * were formatted without exponential notation.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) {
        return this.multiply(rhs, plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
     * <p>
     * Implements the multiplication (<b><code> </code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        com.ibm.icu.math.BigDecimal lhs;
        int padding;
        int reqdig;
        byte multer[] = null;
        byte multand[] = null;
        int multandlen;
        int acclen = 0;
        com.ibm.icu.math.BigDecimal res;
        byte acc[];
        int n = 0;
        byte mult = 0;
        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        lhs = this; // name for clarity and proxy

        /* Prepare numbers (truncate, unless unlimited precision) */
        padding = 0; // trailing 0's to add
        reqdig = set.digits; // local copy
        if (reqdig > 0) {
            if (lhs.mant.length > reqdig)
                lhs = clone(lhs).round(set);
            if (rhs.mant.length > reqdig)
                rhs = clone(rhs).round(set);
            // [we could reuse the new LHS for result in this case]
        } else {/* unlimited */
            // fixed point arithmetic will want every trailing 0; we add these
            // after the calculation rather than before, for speed.
            if (lhs.exp > 0)
                padding = padding + lhs.exp;
            if (rhs.exp > 0)
                padding = padding + rhs.exp;
        }

        // For best speed, as in DMSRCN, we use the shorter number as the
        // multiplier and the longer as the multiplicand.
        // 1999.12.22: We used to special case when the result would fit in
        // a long, but with Java 1.3 this gave no advantage.
        if (lhs.mant.length < rhs.mant.length) {
            multer = lhs.mant;
            multand = rhs.mant;
        } else {
            multer = rhs.mant;
            multand = lhs.mant;
        }

        /* Calculate how long result byte array will be */
        multandlen = (multer.length + multand.length) - 1; // effective length
        // optimize for 75% of the cases where a carry is expected...
        if ((multer[0] * multand[0]) > 9)
            acclen = multandlen + 1;
        else
            acclen = multandlen;

        /* Now the main long multiplication loop */
        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
        acc = new byte[acclen]; // accumulator, all zeros
        // 1998.07.01: calculate from left to right so that accumulator goes
        // to likely final length on first addition; this avoids a one-digit
        // extension (and object allocation) each time around the loop.
        // Initial number therefore has virtual zeros added to right.
        {
            int $7 = multer.length;
            n = 0;
            for (; $7 > 0; $7--, n++) {
                mult = multer[n];
                if (mult != 0) { // [optimization]
                    // accumulate [accumulator is reusable array]
                    acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true);
                }
                // divide multiplicand by 10 for next digit to right
                multandlen--; // 'virtual length'
            }
        }/* n */

        res.ind = (byte) (lhs.ind * rhs.ind); // final sign
        res.exp = (lhs.exp + rhs.exp) - padding; // final exponent
        // [overflow is checked by finish]

        /* add trailing zeros to the result, if necessary */
        if (padding == 0)
            res.mant = acc;
        else
            res.mant = extend(acc, acc.length + padding); // add trailing 0s
        return res.finish(set, false);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>-this</code>.
     * <p>
     * The same as {@link #negate(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>
     * .
     * <p>
     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
     * 
     * 
     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal negate() {
        return this.negate(plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
     * <p>
     * Implements the negation (Prefix <b><code>-</code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) {
        com.ibm.icu.math.BigDecimal res;
        // Originally called minus(), changed to matched Java precedents
        // This simply clones, flips the sign, and possibly rounds
        if (set.lostDigits)
            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
        res = clone(this); // safe copy
        res.ind = (byte) -res.ind;
        return res.finish(set, false);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>+this</code>. Note that <code>this</code> is not
     * necessarily a plain <code>BigDecimal</code>, but the result will always be.
     * <p>
     * The same as {@link #plus(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
     * 
     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal plus() {
        return this.plus(plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>+this</code>.
     * <p>
     * Implements the plus (Prefix <b><code>+</code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * <p>
     * This method is useful for rounding or otherwise applying a context to a decimal value.
     * 
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) {
        // This clones and forces the result to the new settings
        // May return same object
        if (set.lostDigits)
            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
        // Optimization: returns same object for some common cases
        if (set.form == com.ibm.icu.math.MathContext.PLAIN)
            if (this.form == com.ibm.icu.math.MathContext.PLAIN) {
                if (this.mant.length <= set.digits)
                    return this;
                if (set.digits == 0)
                    return this;
            }
        return clone(this).finish(set, false);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
     * <p>
     * The same as {@link #pow(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The parameter is the power to which the <code>this</code> will be raised; it must be in the range 0 through
     * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so
     * they should not be used as a test for a whole number.
     * <p>
     * In addition, the power must not be negative, as no <code>MathContext</code> is used and so the result would then
     * always be 0.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) {
        return this.pow(rhs, plainMC);
    }

    // The name for this method is inherited from the precedent set by the
    // BigInteger and Math classes.

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
     * <p>
     * Implements the power (<b><code> </code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * <p>
     * The first parameter is the power to which the <code>this</code> will be raised; it must be in the range
     * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed
     * in the future, so they should not be used as a test for a whole number.
     * <p>
     * If the <code>digits</code> setting of the <code>MathContext</code> parameter is 0, the power must be zero or
     * positive.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>.
     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        int n;
        com.ibm.icu.math.BigDecimal lhs;
        int reqdig;
        int workdigits = 0;
        int L = 0;
        com.ibm.icu.math.MathContext workset;
        com.ibm.icu.math.BigDecimal res;
        boolean seenbit;
        int i = 0;
        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules
        lhs = this; // clarified name

        reqdig = set.digits; // local copy (heavily used)
        if (reqdig == 0) {
            if (rhs.ind == isneg)
                throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString());
            workdigits = 0;
        } else {/* non-0 digits */
            if ((rhs.mant.length + rhs.exp) > reqdig)
                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());

            /* Round the lhs to DIGITS if need be */
            if (lhs.mant.length > reqdig)
                lhs = clone(lhs).round(set);

            /* L for precision calculation [see ANSI X3.274-1996] */
            L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp
            workdigits = (reqdig + L) + 1; // calculate the working DIGITS
        }

        /* Create a copy of set for working settings */
        // Note: no need to check for lostDigits again.
        // 1999.07.17 Note: this construction must follow RHS check
        workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode);

        res = ONE; // accumulator
        if (n == 0)
            return res; // x**0 == 1
        if (n < 0)
            n = -n; // [rhs.ind records the sign]
        seenbit = false; // set once we've seen a 1-bit
        {
            i = 1;
            i: for (;; i++) { // for each bit [top bit ignored]
                n = n + n; // shift left 1 bit
                if (n < 0) { // top bit is set
                    seenbit = true; // OK, we're off
                    res = res.multiply(lhs, workset); // acc=acc*x
                }
                if (i == 31)
                    break i; // that was the last bit
                if ((!seenbit))
                    continue i; // we don't have to square 1
                res = res.multiply(res, workset); // acc=acc*acc [square]
            }
        }/* i */// 32 bits
        if (rhs.ind < 0) // was a **-n [hence digits>0]
            res = ONE.divide(res, workset); // .. so acc=1/acc
        return res.finish(set, true); // round and strip [original digits]
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
     * arithmetic.
     * <p>
     * The same as {@link #remainder(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * This is not the modulo operator -- the result may be negative.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
     *         arithmetic.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) {
        return this.dodivide('R', rhs, plainMC, -1);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>.
     * <p>
     * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}),
     * and returns the result as a <code>BigDecimal</code> object.
     * <p>
     * This is not the modulo operator -- the result may be negative.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this+rhs</code>.
     * @throws ArithmeticException if <code>rhs</code> is zero.
     * @throws ArithmeticException  if the integer part of the result will not fit in the number of digits specified for the context.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        return this.dodivide('R', rhs, set, -1);
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
     * <p>
     * The same as {@link #subtract(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
     * <p>
     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) {
        return this.subtract(rhs, plainMC);
    }

    /**
     * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
     * <p>
     * Implements the subtraction (<b><code>-</code></b>) operator (as defined in the decimal documentation, see
     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
     * 
     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
     * @param set The <code>MathContext</code> arithmetic settings.
     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
        com.ibm.icu.math.BigDecimal newrhs;
        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        // [add will recheck .. but would report -rhs]
        /* carry out the subtraction */
        // we could fastpath -0, but it is too rare.
        newrhs = clone(rhs); // safe copy
        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
        return this.add(newrhs, set); // arithmetic
    }

    /* ---------------------------------------------------------------- */
    /* Other methods */
    /* ---------------------------------------------------------------- */

    /**
     * Converts this <code>BigDecimal</code> to a <code>byte</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part or is out of the possible range for a <code>byte</code> (8-bit signed integer) result then an <code>
     * ArithmeticException</code> is thrown.
     * 
     * @return A <code>byte</code> equal in value to <code>this</code>.
     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>byte</code>.
     * @stable ICU 2.0
     */

    public byte byteValueExact() {
        int num;
        num = this.intValueExact(); // will check decimal part too
        if ((num > 127) | (num < (-128)))
            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
        return (byte) num;
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>double</code>. If the <code>BigDecimal</code> is out of the
     * possible range for a <code>double</code> (64-bit signed floating point) result then an <code>ArithmeticException
     * </code> is thrown.
     * <p>
     * The double produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
     * then converting it using the <code>Double(String)</code> constructor; this can result in values of <code>
     * Double.NEGATIVE_INFINITY</code> or <code>Double.POSITIVE_INFINITY</code>.
     * 
     * @return A <code>double</code> corresponding to <code>this</code>.
     * @stable ICU 2.0
     */

    public double doubleValue() {
        // We go via a String [as does BigDecimal in JDK 1.2]
        // Next line could possibly raise NumberFormatException
        return java.lang.Double.valueOf(this.toString()).doubleValue();
    }

    /**
     * Compares this <code>BigDecimal</code> with <code>rhs</code> for equality.
     * <p>
     * If the parameter is <code>null</code>, or is not an instance of the BigDecimal type, or is not exactly equal to
     * the current <code>BigDecimal</code> object, then <i>false</i> is returned. Otherwise, <i>true</i> is returned.
     * <p>
     * "Exactly equal", here, means that the <code>String</code> representations of the <code>BigDecimal</code> numbers
     * are identical (they have the same characters in the same sequence).
     * <p>
     * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons.
     * 
     * @param obj The <code>Object</code> for the right hand side of the comparison.
     * @return A <code>boolean</code> whose value <i>true</i> if and only if the operands have identical string
     *         representations.
     * @throws ClassCastException if <code>rhs</code> cannot be cast to a <code>BigDecimal</code> object.
     * @stable ICU 2.0
     * @see #compareTo(BigDecimal)
     * @see #compareTo(BigDecimal, MathContext)
     */

    public boolean equals(java.lang.Object obj) {
        com.ibm.icu.math.BigDecimal rhs;
        int i = 0;
        char lca[] = null;
        char rca[] = null;
        // We are equal iff toString of both are exactly the same
        if (obj == null)
            return false; // not equal
        if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
            return false; // not a decimal
        rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work
        if (this.ind != rhs.ind)
            return false; // different signs never match
        if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form))

        { // mantissas say all
            // here with equal-length byte arrays to compare
            {
                int $8 = this.mant.length;
                i = 0;
                for (; $8 > 0; $8--, i++) {
                    if (this.mant[i] != rhs.mant[i])
                        return false;
                }
            }/* i */
        } else { // need proper layout
            lca = this.layout(); // layout to character array
            rca = rhs.layout();
            if (lca.length != rca.length)
                return false; // mismatch
            // here with equal-length character arrays to compare
            {
                int $9 = lca.length;
                i = 0;
                for (; $9 > 0; $9--, i++) {
                    if (lca[i] != rca[i])
                        return false;
                }
            }/* i */
        }
        return true; // arrays have identical content
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>float</code>. If the <code>BigDecimal</code> is out of the
     * possible range for a <code>float</code> (32-bit signed floating point) result then an <code>ArithmeticException
     * </code> is thrown.
     * <p>
     * The float produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
     * then converting it using the <code>Float(String)</code> constructor; this can result in values of <code>
     * Float.NEGATIVE_INFINITY</code> or <code>Float.POSITIVE_INFINITY</code>.
     * 
     * @return A <code>float</code> corresponding to <code>this</code>.
     * @stable ICU 2.0
     */

    public float floatValue() {
        return java.lang.Float.valueOf(this.toString()).floatValue();
    }

    /**
     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters.
     * <p>
     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
     * </i>
     * <p>
     * The parameters, for both forms of the <code>format</code> method are all of type <code>int</code>. A value of -1
     * for any parameter indicates that the default action or value for that parameter should be used.
     * <p>
     * The parameters, <code>before</code> and <code>after</code>, specify the number of characters to be used for the
     * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter
     * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed
     * for that part.
     * <p>
     * <code>before</code> must be a positive number; if it is larger than is needed to contain the integer part, that
     * part is padded on the left with blanks to the requested length. If <code>before</code> is not large enough to
     * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown.
     * <p>
     * <code>after</code> must be a non-negative number; if it is not the same size as the decimal part of the number,
     * the number will be rounded (or extended with zeros) to fit. Specifying 0 for <code>after</code> will cause the
     * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method
     * will be the default, <code>MathContext.ROUND_HALF_UP</code>.
     * <p>
     * Other rounding methods, and the use of exponential notation, can be selected by using
     * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect
     * as using the six-parameter form with the final four parameters all being -1.
     * 
     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as are needed'.
     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as are needed'.
     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified parameters
     * @throws ArithmeticException if the number cannot be laid out as requested.
     * @throws IllegalArgumentException if a parameter is out of range.
     * @stable ICU 2.0
     * @see #toString
     * @see #toCharArray
     */

    public java.lang.String format(int before, int after) {
        return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP);
    }

    /**
     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters and
     * allowing exponential notation.
     * <p>
     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
     * </i>
     * <p>
     * The parameters are all of type <code>int</code>. A value of -1 for any parameter indicates that the default
     * action or value for that parameter should be used.
     * <p>
     * The first two parameters (<code>before</code> and <code>after</code>) specify the number of characters to be used
     * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If
     * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many
     * as are needed for that part.
     * <p>
     * The remaining parameters control the use of exponential notation and rounding. Three (<code>explaces</code>,
     * <code>exdigits</code>, and <code>exform</code>) control the exponent part of the result. As before, the default
     * action for any of these parameters may be selected by using the value -1.
     * <p>
     * <code>explaces</code> must be a positive number; it sets the number of places (digits after the sign of the
     * exponent) to be used for any exponent part, the default (when <code>explaces</code> is -1) being to use as many
     * as are needed. If <code>explaces</code> is not -1, space is always reserved for an exponent; if one is not needed
     * (for example, if the exponent will be 0) then <code>explaces</code>+2 blanks are appended to the result. <!--
     * (This preserves vertical alignment of similarly formatted numbers in a monospace font.) --> If <code>explaces
     * </code> is not -1 and is not large enough to contain the exponent, an exception is thrown.
     * <p>
     * <code>exdigits</code> sets the trigger point for use of exponential notation. If, before any rounding, the number
     * of places needed before the decimal point exceeds <code>exdigits</code>, or if the absolute value of the result
     * is less than <code>0.000001</code>, then exponential form will be used, provided that <code>exdigits</code> was
     * specified. When <code>exdigits</code> is -1, exponential notation will never be used. If 0 is specified for
     * <code>exdigits</code>, exponential notation is always used unless the exponent would be 0.
     * <p>
     * <code>exform</code> sets the form for exponential notation (if needed). It may be either
     * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested,
     * up to three digits (plus sign, if negative) may be needed for the integer part of the result (<code>before</code>
     * ). Otherwise, only one digit (plus sign, if negative) is needed.
     * <p>
     * Finally, the sixth argument, <code>exround</code>, selects the rounding algorithm to be used, and must be one of
     * the values indicated by a public constant in the {@link MathContext} class whose name starts with <code>ROUND_
     * </code>. The default (<code>ROUND_HALF_UP</code>) may also be selected by using the value -1, as before.
     * <p>
     * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be used to detect whether non-zero digits are
     * discarded -- if <code>exround</code> has this value than if non-zero digits would be discarded (rounded) during
     * formatting then an <code>ArithmeticException</code> is thrown.
     * 
     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as
     *            are needed'.
     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as
     *            are needed'.
     * @param explaces The <code>int</code> specifying the number of places to be used for any exponent. Use -1 for 'as many
     *            as are needed'.
     * @param exdigits The <code>int</code> specifying the trigger (digits before the decimal point) which if exceeded causes
     *            exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation
     *            (no exponential notation).
     * @param exformint The <code>int</code> specifying the form of exponential notation to be used (
     *            {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}).
     * @param exround The <code>int</code> specifying the rounding mode to use. Use -1 for the default,
     *            {@link MathContext#ROUND_HALF_UP}.
     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified
     *         parameters
     * @throws ArithmeticException if the number cannot be laid out as requested.
     * @throws IllegalArgumentException if a parameter is out of range.
     * @see #toString
     * @see #toCharArray
     * @stable ICU 2.0
     */

    public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) {
        com.ibm.icu.math.BigDecimal num;
        int mag = 0;
        int thisafter = 0;
        int lead = 0;
        byte newmant[] = null;
        int chop = 0;
        int need = 0;
        int oldexp = 0;
        char a[];
        int p = 0;
        char newa[] = null;
        int i = 0;
        int places = 0;

        /* Check arguments */
        if ((before < (-1)) | (before == 0))
            badarg("format", 1, java.lang.String.valueOf(before));
        if (after < (-1))
            badarg("format", 2, java.lang.String.valueOf(after));
        if ((explaces < (-1)) | (explaces == 0))
            badarg("format", 3, java.lang.String.valueOf(explaces));
        if (exdigits < (-1))
            badarg("format", 4, java.lang.String.valueOf(explaces));
        {/* select */
            if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) {
            } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) {
            } else if (exformint == (-1))
                exformint = com.ibm.icu.math.MathContext.SCIENTIFIC;
            // note PLAIN isn't allowed
            else {
                badarg("format", 5, java.lang.String.valueOf(exformint));
            }
        }
        // checking the rounding mode is done by trying to construct a
        // MathContext object with that mode; it will fail if bad
        if (exround != ROUND_HALF_UP) {
            try { // if non-default...
                if (exround == (-1))
                    exround = ROUND_HALF_UP;
                else
                    new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround);
            } catch (java.lang.IllegalArgumentException $10) {
                badarg("format", 6, java.lang.String.valueOf(exround));
            }
        }

        num = clone(this); // make private copy

        /*
         * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0]
         * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two]
         * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified
         */

        /* determine form */
        {
            do {/* select */
                if (exdigits == (-1))
                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
                else if (num.ind == iszero)
                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
                else {
                    // determine whether triggers
                    mag = num.exp + num.mant.length;
                    if (mag > exdigits)
                        num.form = (byte) exformint;
                    else if (mag < (-5))
                        num.form = (byte) exformint;
                    else
                        num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
                }
            } while (false);
        }/* setform */

        /*
         * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform
         * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific).
         */
        if (after >= 0) {
            setafter: for (;;) {
                // calculate the current after-length
                {/* select */
                    if (num.form == com.ibm.icu.math.MathContext.PLAIN)
                        thisafter = -num.exp; // has decimal part
                    else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC)
                        thisafter = num.mant.length - 1;
                    else { // engineering
                        lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use
                        if (lead < 0)
                            lead = 3 + lead; // negative exponent case
                        lead++; // number of leading digits
                        if (lead >= num.mant.length)
                            thisafter = 0;
                        else
                            thisafter = num.mant.length - lead;
                    }
                }
                if (thisafter == after)
                    break setafter; // we're in luck
                if (thisafter < after) { // need added trailing zeros
                    // [thisafter can be negative]
                    newmant = extend(num.mant, (num.mant.length + after) - thisafter);
                    num.mant = newmant;
                    num.exp = num.exp - ((after - thisafter)); // adjust exponent
                    if (num.exp < MinExp)
                        throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp);
                    break setafter;
                }
                // We have too many digits after the decimal point; this could
                // cause a carry, which could change the mantissa...
                // Watch out for implied leading zeros in PLAIN case
                chop = thisafter - after; // digits to lop [is >0]
                if (chop > num.mant.length) { // all digits go, no chance of carry
                    // carry on with zero
                    num.mant = ZERO.mant;
                    num.ind = iszero;
                    num.exp = 0;
                    continue setafter; // recheck: we may need trailing zeros
                }
                // we have a digit to inspect from existing mantissa
                // round the number as required
                need = num.mant.length - chop; // digits to end up with [may be 0]
                oldexp = num.exp; // save old exponent
                num.round(need, exround);
                // if the exponent grew by more than the digits we chopped, then
                // we must have had a carry, so will need to recheck the layout
                if ((num.exp - oldexp) == chop)
                    break setafter; // number did not have carry
                // mantissa got extended .. so go around and check again
            }
        }/* setafter */

        a = num.layout(); // lay out, with exponent if required, etc.

        /* Here we have laid-out number in 'a' */
        // now apply 'before' and 'explaces' as needed
        if (before > 0) {
            // look for '.' or 'E'
            {
                int $11 = a.length;
                p = 0;
                p: for (; $11 > 0; $11--, p++) {
                    if (a[p] == '.')
                        break p;
                    if (a[p] == 'E')
                        break p;
                }
            }/* p */
            // p is now offset of '.', 'E', or character after end of array
            // that is, the current length of before part
            if (p > before)
                badarg("format", 1, java.lang.String.valueOf(before)); // won't fit
            if (p < before) { // need leading blanks
                newa = new char[(a.length + before) - p];
                {
                    int $12 = before - p;
                    i = 0;
                    for (; $12 > 0; $12--, i++) {
                        newa[i] = ' ';
                    }
                }/* i */
                java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, i, a.length);
                a = newa;
            }
            // [if p=before then it's just the right length]
        }

        if (explaces > 0) {
            // look for 'E' [cannot be at offset 0]
            {
                int $13 = a.length - 1;
                p = a.length - 1;
                p: for (; $13 > 0; $13--, p--) {
                    if (a[p] == 'E')
                        break p;
                }
            }/* p */
            // p is now offset of 'E', or 0
            if (p == 0) { // no E part; add trailing blanks
                newa = new char[(a.length + explaces) + 2];
                java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, a.length);
                {
                    int $14 = explaces + 2;
                    i = a.length;
                    for (; $14 > 0; $14--, i++) {
                        newa[i] = ' ';
                    }
                }/* i */
                a = newa;
            } else {/* found E */// may need to insert zeros
                places = (a.length - p) - 2; // number so far
                if (places > explaces)
                    badarg("format", 3, java.lang.String.valueOf(explaces));
                if (places < explaces) { // need to insert zeros
                    newa = new char[(a.length + explaces) - places];
                    java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, p + 2); // through E
                                                                                                            // and sign
                    {
                        int $15 = explaces - places;
                        i = p + 2;
                        for (; $15 > 0; $15--, i++) {
                            newa[i] = '0';
                        }
                    }/* i */
                    java.lang.System.arraycopy((java.lang.Object) a, p + 2, (java.lang.Object) newa, i, places); // remainder
                                                                                                                 // of
                                                                                                                 // exponent
                    a = newa;
                }
                // [if places=explaces then it's just the right length]
            }
        }
        return new java.lang.String(a);
    }

    /**
     * Returns the hashcode for this <code>BigDecimal</code>. This hashcode is suitable for use by the <code>
     * java.util.Hashtable</code> class.
     * <p>
     * Note that two <code>BigDecimal</code> objects are only guaranteed to produce the same hashcode if they are
     * exactly equal (that is, the <code>String</code> representations of the <code>BigDecimal</code> numbers are
     * identical -- they have the same characters in the same sequence).
     * 
     * @return An <code>int</code> that is the hashcode for <code>this</code>.
     * @stable ICU 2.0
     */

    public int hashCode() {
        // Maybe calculate ourselves, later. If so, note that there can be
        // more than one internal representation for a given toString() result.
        return this.toString().hashCode();
    }

    /**
     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for an <code>int</code>
     * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be
     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact}
     * method.
     * 
     * @return An <code>int</code> converted from <code>this</code>, truncated and decapitated if necessary.
     * @stable ICU 2.0
     */

    public int intValue() {
        return toBigInteger().intValue();
    }

    /**
     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part or is out of the possible range for an <code>int</code> (32-bit signed integer) result then an
     * <code>ArithmeticException</code> is thrown.
     * 
     * @return An <code>int</code> equal in value to <code>this</code>.
     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in an <code>int</code>.
     * @stable ICU 2.0
     */

    public int intValueExact() {
        int lodigit;
        int useexp = 0;
        int result;
        int i = 0;
        int topdig = 0;
        // This does not use longValueExact() as the latter can be much
        // slower.
        // intcheck (from pow) relies on this to check decimal part
        if (ind == iszero)
            return 0; // easy, and quite common
        /* test and drop any trailing decimal part */
        lodigit = mant.length - 1;
        if (exp < 0) {
            lodigit = lodigit + exp; // reduces by -(-exp)
            /* all decimal places must be 0 */
            if ((!(allzero(mant, lodigit + 1))))
                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
            if (lodigit < 0)
                return 0; // -1<this<1
            useexp = 0;
        } else {/* >=0 */
            if ((exp + lodigit) > 9) // early exit
                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
            useexp = exp;
        }
        /* convert the mantissa to binary, inline for speed */
        result = 0;
        {
            int $16 = lodigit + useexp;
            i = 0;
            for (; i <= $16; i++) {
                result = result * 10;
                if (i <= lodigit)
                    result = result + mant[i];
            }
        }/* i */

        /* Now, if the risky length, check for overflow */
        if ((lodigit + useexp) == 9) {
            // note we cannot just test for -ve result, as overflow can move a
            // zero into the top bit [consider 5555555555]
            topdig = result / 1000000000; // get top digit, preserving sign
            if (topdig != mant[0]) { // digit must match and be positive
                // except in the special case ...
                if (result == java.lang.Integer.MIN_VALUE) // looks like the special
                    if (ind == isneg) // really was negative
                        if (mant[0] == 2)
                            return result; // really had top digit 2
                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
            }
        }

        /* Looks good */
        if (ind == ispos)
            return result;
        return -result;
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for a <code>long</code>
     * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be
     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact}
     * method.
     * 
     * @return A <code>long</code> converted from <code>this</code>, truncated and decapitated if necessary.
     * @stable ICU 2.0
     */

    public long longValue() {
        return toBigInteger().longValue();
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part or is out of the possible range for a <code>long</code> (64-bit signed integer) result then an
     * <code>ArithmeticException</code> is thrown.
     * 
     * @return A <code>long</code> equal in value to <code>this</code>.
     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>long</code>.
     * @stable ICU 2.0
     */

    public long longValueExact() {
        int lodigit;
        int cstart = 0;
        int useexp = 0;
        long result;
        int i = 0;
        long topdig = 0;
        // Identical to intValueExact except for result=long, and exp>=20 test
        if (ind == 0)
            return 0; // easy, and quite common
        lodigit = mant.length - 1; // last included digit
        if (exp < 0) {
            lodigit = lodigit + exp; // -(-exp)
            /* all decimal places must be 0 */
            if (lodigit < 0)
                cstart = 0;
            else
                cstart = lodigit + 1;
            if ((!(allzero(mant, cstart))))
                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
            if (lodigit < 0)
                return 0; // -1<this<1
            useexp = 0;
        } else {/* >=0 */
            if ((exp + mant.length) > 18) // early exit
                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
            useexp = exp;
        }

        /* convert the mantissa to binary, inline for speed */
        // note that we could safely use the 'test for wrap to negative'
        // algorithm here, but instead we parallel the intValueExact
        // algorithm for ease of checking and maintenance.
        result = (long) 0;
        {
            int $17 = lodigit + useexp;
            i = 0;
            for (; i <= $17; i++) {
                result = result * 10;
                if (i <= lodigit)
                    result = result + mant[i];
            }
        }/* i */

        /* Now, if the risky length, check for overflow */
        if ((lodigit + useexp) == 18) {
            topdig = result / 1000000000000000000L; // get top digit, preserving sign
            if (topdig != mant[0]) { // digit must match and be positive
                // except in the special case ...
                if (result == java.lang.Long.MIN_VALUE) // looks like the special
                    if (ind == isneg) // really was negative
                        if (mant[0] == 9)
                            return result; // really had top digit 9
                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
            }
        }

        /* Looks good */
        if (ind == ispos)
            return result;
        return -result;
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the left by a specified number of
     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
     * if <code>n</code> is 0 or positive, the number returned is given by:
     * <p>
     * <code> this.multiply(TEN.pow(new BigDecimal(-n))) </code>
     * <p>
     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointRight(-n)
     * </code>.
     * 
     * @param n The <code>int</code> specifying the number of places to move the decimal point leftwards.
     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
     *         places to the left.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal movePointLeft(int n) {
        com.ibm.icu.math.BigDecimal res;
        // very little point in optimizing for shift of 0
        res = clone(this);
        res.exp = res.exp - n;
        return res.finish(plainMC, false); // finish sets form and checks exponent
    }

    /**
     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the right by a specified number of
     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
     * if <code>n</code> is 0 or positive, the number returned is given by:
     * <p>
     * <code> this.multiply(TEN.pow(new BigDecimal(n))) </code>
     * <p>
     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointLeft(-n)
     * </code>.
     * 
     * @param n The <code>int</code> specifying the number of places to move the decimal point rightwards.
     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
     *         places to the right.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal movePointRight(int n) {
        com.ibm.icu.math.BigDecimal res;
        res = clone(this);
        res.exp = res.exp + n;
        return res.finish(plainMC, false);
    }

    /**
     * Returns the scale of this <code>BigDecimal</code>. Returns a non-negative <code>int</code> which is the scale of
     * the number. The scale is the number of digits in the decimal part of the number if the number were formatted
     * without exponential notation.
     * 
     * @return An <code>int</code> whose value is the scale of this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public int scale() {
        if (exp >= 0)
            return 0; // scale can never be negative
        return -exp;
    }

    /**
     * Returns a plain <code>BigDecimal</code> with a given scale.
     * <p>
     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
     * <p>
     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
     * trailing digits will be removed, and in this case an <code>ArithmeticException</code> is thrown if any discarded
     * digits are non-zero.
     * <p>
     * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is <code>
     * MathContext.ROUND_UNNECESSARY</code>.
     * 
     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
     * @return A plain <code>BigDecimal</code> with the given scale.
     * @throws ArithmeticException if <code>scale</code> is negative.
     * @throws ArithmeticException if reducing scale would discard non-zero digits.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal setScale(int scale) {
        return setScale(scale, ROUND_UNNECESSARY);
    }

    /**
     * Returns a plain <code>BigDecimal</code> with a given scale.
     * <p>
     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
     * <p>
     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
     * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the
     * remaining digits are affected by a carry. In this case, an <code>IllegalArgumentException</code> is thrown if
     * <code>round</code> is not a valid rounding mode.
     * <p>
     * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, an <code>ArithmeticException</code> is
     * thrown if any discarded digits are non-zero.
     * 
     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
     * @return A plain <code>BigDecimal</code> with the given scale.
     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
     * @throws ArithmeticException if <code>scale</code> is negative.
     * @throws ArithmeticException if <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, and reducing scale would discard
     *             non-zero digits.
     * @stable ICU 2.0
     */

    public com.ibm.icu.math.BigDecimal setScale(int scale, int round) {
        int ourscale;
        com.ibm.icu.math.BigDecimal res;
        int padding = 0;
        int newlen = 0;
        // at present this naughtily only checks the round value if it is
        // needed (used), for speed
        ourscale = this.scale();
        if (ourscale == scale) // already correct scale
            if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form
                return this;
        res = clone(this); // need copy
        if (ourscale <= scale) { // simply zero-padding/changing form
            // if ourscale is 0 we may have lots of 0s to add
            if (ourscale == 0)
                padding = res.exp + scale;
            else
                padding = scale - ourscale;
            res.mant = extend(res.mant, res.mant.length + padding);
            res.exp = -scale; // as requested
        } else {/* ourscale>scale: shortening, probably */
            if (scale < 0)
                throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
            // [round() will raise exception if invalid round]
            newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK]
            res = res.round(newlen, round); // round to required length
            // This could have shifted left if round (say) 0.9->1[.0]
            // Repair if so by adding a zero and reducing exponent
            if (res.exp != -scale) {
                res.mant = extend(res.mant, res.mant.length + 1);
                res.exp = res.exp - 1;
            }
        }
        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition
        return res;
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>short</code>. If the <code>BigDecimal</code> has a non-zero
     * decimal part or is out of the possible range for a <code>short</code> (16-bit signed integer) result then an
     * <code>ArithmeticException</code> is thrown.
     * 
     * @return A <code>short</code> equal in value to <code>this</code>.
     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>short</code>.
     * @stable ICU 2.0
     */

    public short shortValueExact() {
        int num;
        num = this.intValueExact(); // will check decimal part too
        if ((num > 32767) | (num < (-32768)))
            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
        return (short) num;
    }

    /**
     * Returns the sign of this <code>BigDecimal</code>, as an <code>int</code>. This returns the <i>signum</i> function
     * value that represents the sign of this <code>BigDecimal</code>. That is, -1 if the <code>BigDecimal</code> is
     * negative, 0 if it is numerically equal to zero, or 1 if it is positive.
     * 
     * @return An <code>int</code> which is -1 if the <code>BigDecimal</code> is negative, 0 if it is numerically equal
     *         to zero, or 1 if it is positive.
     * @stable ICU 2.0
     */

    public int signum() {
        return (int) this.ind; // [note this assumes values for ind.]
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>java.math.BigDecimal</code>.
     * <p>
     * This is an exact conversion; the result is the same as if the <code>BigDecimal</code> were formatted as a plain
     * number without any rounding or exponent and then the <code>java.math.BigDecimal(java.lang.String)</code>
     * constructor were used to construct the result.
     * <p>
     * <i>(Note: this method is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class. It
     * would not be present in a <code>java.math</code> version.)</i>
     * 
     * @return The <code>java.math.BigDecimal</code> equal in value to this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public java.math.BigDecimal toBigDecimal() {
        return new java.math.BigDecimal(this.unscaledValue(), this.scale());
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
     * <p>
     * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use
     * {@link #toBigIntegerExact()}.
     * 
     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public java.math.BigInteger toBigInteger() {
        com.ibm.icu.math.BigDecimal res = null;
        int newlen = 0;
        byte newmant[] = null;
        {/* select */
            if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN))
                res = this; // can layout simply
            else if (exp >= 0) {
                res = clone(this); // safe copy
                res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
            } else {
                { // exp<0; scale to be truncated
                    // we could use divideInteger, but we may as well be quicker
                    if (-this.exp >= this.mant.length)
                        res = ZERO; // all blows away
                    else {
                        res = clone(this); // safe copy
                        newlen = res.mant.length + res.exp;
                        newmant = new byte[newlen]; // [shorter]
                        java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0,
                                newlen);
                        res.mant = newmant;
                        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
                        res.exp = 0;
                    }
                }
            }
        }
        return new BigInteger(new java.lang.String(res.layout()));
    }

    /**
     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
     * <p>
     * An exception is thrown if the decimal part (if any) is non-zero.
     * 
     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part.
     * @stable ICU 2.0
     */

    public java.math.BigInteger toBigIntegerExact() {
        /* test any trailing decimal part */
        if (exp < 0) { // possible decimal part
            /* all decimal places must be 0; note exp<0 */
            if ((!(allzero(mant, mant.length + exp))))
                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
        }
        return toBigInteger();
    }

    /**
     * Returns the <code>BigDecimal</code> as a character array. The result of this method is the same as using the
     * sequence <code>toString().toCharArray()</code>, but avoids creating the intermediate <code>String</code> and
     * <code>char[]</code> objects.
     * 
     * @return The <code>char[]</code> array corresponding to this <code>BigDecimal</code>.
     * @stable ICU 2.0
     */

    public char[] toCharArray() {
        return layout();
    }

    /**
     * Returns the <code>BigDecimal</code> as a <code>String</code>. This returns a <code>String</code> that exactly
     * represents this <code>BigDecimal</code>, as defined in the decimal documentation (see {@link BigDecimal class
     * header}).
     * <p>
     * By definition, using the {@link #BigDecimal(String)} constructor on the result <code>String</code> will create a
     * <code>BigDecimal</code> that is exactly equal to the original <code>BigDecimal</code>.
     * 
     * @return The <code>String</code> exactly corresponding to this <code>BigDecimal</code>.
     * @see #format(int, int)
     * @see #format(int, int, int, int, int, int)
     * @see #toCharArray()
     * @stable ICU 2.0
     */

    public java.lang.String toString() {
        return new java.lang.String(layout());
    }

    /**
     * Returns the number as a <code>BigInteger</code> after removing the scale. That is, the number is expressed as a
     * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is
     * then converted to a <code>BigInteger</code>.
     * 
     * @return The <code>java.math.BigInteger</code> equal in value to this <code>BigDecimal</code> multiplied by ten to
     *         the power of <code>this.scale()</code>.
     * @stable ICU 2.0
     */

    public java.math.BigInteger unscaledValue() {
        com.ibm.icu.math.BigDecimal res = null;
        if (exp >= 0)
            res = this;
        else {
            res = clone(this); // safe copy
            res.exp = 0; // drop scale
        }
        return res.toBigInteger();
    }

    /**
     * Translates a <code>double</code> to a <code>BigDecimal</code>.
     * <p>
     * Returns a <code>BigDecimal</code> which is the decimal representation of the 64-bit signed binary floating point
     * parameter. If the parameter is infinite, or is not a number (NaN), a <code>NumberFormatException</code> is
     * thrown.
     * <p>
     * The number is constructed as though <code>num</code> had been converted to a <code>String</code> using the <code>
     * Double.toString()</code> method and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
     * This is typically not an exact conversion.
     * 
     * @param dub The <code>double</code> to be translated.
     * @return The <code>BigDecimal</code> equal in value to <code>dub</code>.
     * @throws NumberFormatException if the parameter is infinite or not a number.
     * @stable ICU 2.0
     */

    public static com.ibm.icu.math.BigDecimal valueOf(double dub) {
        // Reminder: a zero double returns '0.0', so we cannot fastpath to
        // use the constant ZERO. This might be important enough to justify
        // a factory approach, a cache, or a few private constants, later.
        return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());
    }

    /**
     * Translates a <code>long</code> to a <code>BigDecimal</code>. That is, returns a plain <code>BigDecimal</code>
     * whose value is equal to the given <code>long</code>.
     * 
     * @param lint The <code>long</code> to be translated.
     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
     * @stable ICU 2.0
     */

    public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
        return valueOf(lint, 0);
    }

    /**
     * Translates a <code>long</code> to a <code>BigDecimal</code> with a given scale. That is, returns a plain <code>
     * BigDecimal</code> whose unscaled value is equal to the given <code>long</code>, adjusted by the second parameter,
     * <code>scale</code>.
     * <p>
     * The result is given by:
     * <p>
     * <code> (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) </code>
     * <p>
     * A <code>NumberFormatException</code> is thrown if <code>scale</code> is negative.
     * 
     * @param lint The <code>long</code> to be translated.
     * @param scale The <code>int</code> scale to be applied.
     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
     * @throws NumberFormatException if the scale is negative.
     * @stable ICU 2.0
     */

    public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) {
        com.ibm.icu.math.BigDecimal res = null;
        {/* select */
            if (lint == 0)
                res = ZERO;
            else if (lint == 1)
                res = ONE;
            else if (lint == 10)
                res = TEN;
            else {
                res = new com.ibm.icu.math.BigDecimal(lint);
            }
        }
        if (scale == 0)
            return res;
        if (scale < 0)
            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
        res = clone(res); // safe copy [do not mutate]
        res.exp = -scale; // exponent is -scale
        return res;
    }

    /* ---------------------------------------------------------------- */
    /* Private methods */
    /* ---------------------------------------------------------------- */

    /*
     * <sgml> Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array).
     * <p>The mantissa will either already have been rounded (following an operation) or will be of length appropriate
     * (in the case of construction from an int, for example). <p>We must not alter the mantissa, here. <p>'form'
     * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure
     * numeric. </sgml>
     */

    private char[] layout() {
        char cmant[];
        int i = 0;
        StringBuilder sb = null;
        int euse = 0;
        int sig = 0;
        char csign = 0;
        char rec[] = null;
        int needsign;
        int mag;
        int len = 0;
        cmant = new char[mant.length]; // copy byte[] to a char[]
        {
            int $18 = mant.length;
            i = 0;
            for (; $18 > 0; $18--, i++) {
                cmant[i] = (char) (mant[i] + ((int) ('0')));
            }
        }/* i */

        if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */
            sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999
            if (ind == isneg)
                sb.append('-');
            euse = (exp + cmant.length) - 1; // exponent to use
            /* setup sig=significant digits and copy to result */
            if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default]
                sb.append(cmant[0]); // significant character
                if (cmant.length > 1) // have decimal part
                    sb.append('.').append(cmant, 1, cmant.length - 1);
            } else {
                do {
                    sig = euse % 3; // common
                    if (sig < 0)
                        sig = 3 + sig; // negative exponent
                    euse = euse - sig;
                    sig++;
                    if (sig >= cmant.length) { // zero padding may be needed
                        sb.append(cmant, 0, cmant.length);
                        {
                            int $19 = sig - cmant.length;
                            for (; $19 > 0; $19--) {
                                sb.append('0');
                            }
                        }
                    } else { // decimal point needed
                        sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig);
                    }
                } while (false);
            }/* engineering */
            if (euse != 0) {
                if (euse < 0) {
                    csign = '-';
                    euse = -euse;
                } else
                    csign = '+';
                sb.append('E').append(csign).append(euse);
            }
            rec = new char[sb.length()];
            int srcEnd = sb.length();
            if (0 != srcEnd) {
                sb.getChars(0, srcEnd, rec, 0);
            }
            return rec;
        }

        /* Here for non-exponential (plain) notation */
        if (exp == 0) {/* easy */
            if (ind >= 0)
                return cmant; // non-negative integer
            rec = new char[cmant.length + 1];
            rec[0] = '-';
            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, 1, cmant.length);
            return rec;
        }

        /* Need a '.' and/or some zeros */
        needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1

        /*
         * MAG is the position of the point in the mantissa (index of the character it follows)
         */
        mag = exp + cmant.length;

        if (mag < 1) {/* 0.00xxxx form */
            len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length
            rec = new char[len];
            if (needsign != 0)
                rec[0] = '-';
            rec[needsign] = '0';
            rec[needsign + 1] = '.';
            {
                int $20 = -mag;
                i = needsign + 2;
                for (; $20 > 0; $20--, i++) { // maybe none
                    rec[i] = '0';
                }
            }/* i */
            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, (needsign + 2) - mag,
                    cmant.length);
            return rec;
        }

        if (mag > cmant.length) {/* xxxx0000 form */
            len = needsign + mag;
            rec = new char[len];
            if (needsign != 0)
                rec[0] = '-';
            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, cmant.length);
            {
                int $21 = mag - cmant.length;
                i = needsign + cmant.length;
                for (; $21 > 0; $21--, i++) { // never 0
                    rec[i] = '0';
                }
            }/* i */
            return rec;
        }

        /* decimal point is in the middle of the mantissa */
        len = (needsign + 1) + cmant.length;
        rec = new char[len];
        if (needsign != 0)
            rec[0] = '-';
        java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, mag);
        rec[needsign + mag] = '.';
        java.lang.System.arraycopy((java.lang.Object) cmant, mag, (java.lang.Object) rec, (needsign + mag) + 1,
                cmant.length - mag);
        return rec;
    }

    /*
     * <sgml> Checks a BigDecimal argument to ensure it's a true integer in a given range. <p>If OK, returns it as an
     * int. </sgml>
     */
    // [currently only used by pow]
    private int intcheck(int min, int max) {
        int i;
        i = this.intValueExact(); // [checks for non-0 decimal part]
        // Use same message as though intValueExact failed due to size
        if ((i < min) | (i > max))
            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i);
        return i;
    }

    /* <sgml> Carry out division operations. </sgml> */
    /*
     * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is
     * explicit scale iff code='D' or 'I' (-1 if none).
     * 
     * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity):
     * 
     * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1)
     * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for
     * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave
     * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -)
     * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If
     * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor
     * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do
     * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if
     * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1
     * 
     * For extended commentary, see DMSRCN.
     */

    private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs,
            com.ibm.icu.math.MathContext set, int scale) {
        com.ibm.icu.math.BigDecimal lhs;
        int reqdig;
        int newexp;
        com.ibm.icu.math.BigDecimal res;
        int newlen;
        byte var1[];
        int var1len;
        byte var2[];
        int var2len;
        int b2b;
        int have;
        int thisdigit = 0;
        int i = 0;
        byte v2 = 0;
        int ba = 0;
        int mult = 0;
        int start = 0;
        int padding = 0;
        int d = 0;
        byte newvar1[] = null;
        byte lasthave = 0;
        int actdig = 0;
        byte newmant[] = null;

        if (set.lostDigits)
            checkdigits(rhs, set.digits);
        lhs = this; // name for clarity

        // [note we must have checked lostDigits before the following checks]
        if (rhs.ind == 0)
            throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
        if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s]
            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
                return ZERO;
            if (scale == (-1))
                return lhs;
            return lhs.setScale(scale);
        }

        /* Prepare numbers according to BigDecimal rules */
        reqdig = set.digits; // local copy (heavily used)
        if (reqdig > 0) {
            if (lhs.mant.length > reqdig)
                lhs = clone(lhs).round(set);
            if (rhs.mant.length > reqdig)
                rhs = clone(rhs).round(set);
        } else {/* scaled divide */
            if (scale == (-1))
                scale = lhs.scale();
            // set reqdig to be at least large enough for the computation
            reqdig = lhs.mant.length; // base length
            // next line handles both positive lhs.exp and also scale mismatch
            if (scale != -lhs.exp)
                reqdig = (reqdig + scale) + lhs.exp;
            reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect
            if (reqdig < lhs.mant.length)
                reqdig = lhs.mant.length; // clamp
            if (reqdig < rhs.mant.length)
                reqdig = rhs.mant.length; // ..
        }

        /* precalculate exponent */
        newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length;
        /* If new exponent -ve, then some quick exits are possible */
        if (newexp < 0)
            if (code != 'D') {
                if (code == 'I')
                    return ZERO; // easy - no integer part
                /* Must be 'R'; remainder is [finished clone of] input value */
                return clone(lhs).finish(set, false);
            }

        /* We need slow division */
        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
        res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I)
        res.exp = newexp; // initial exponent (for D/I)
        res.mant = new byte[reqdig + 1]; // where build the result

        /* Now [virtually pad the mantissae with trailing zeros */
        // Also copy the LHS, which will be our working array
        newlen = (reqdig + reqdig) + 1;
        var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array
        var1len = newlen; // [remaining digits are 0]

        var2 = rhs.mant;
        var2len = newlen;

        /* Calculate first two digits of rhs (var2), +1 for later estimations */
        b2b = (var2[0] * 10) + 1;
        if (var2.length > 1)
            b2b = b2b + var2[1];

        /* start the long-division loops */
        have = 0;
        {
            outer: for (;;) {
                thisdigit = 0;
                /* find the next digit */
                {
                    inner: for (;;) {
                        if (var1len < var2len)
                            break inner; // V1 too low
                        if (var1len == var2len) { // compare needed
                            {
                                compare: do { // comparison
                                    {
                                        int $22 = var1len;
                                        i = 0;
                                        for (; $22 > 0; $22--, i++) {
                                            // var1len is always <= var1.length
                                            if (i < var2.length)
                                                v2 = var2[i];
                                            else
                                                v2 = (byte) 0;
                                            if (var1[i] < v2)
                                                break inner; // V1 too low
                                            if (var1[i] > v2)
                                                break compare; // OK to subtract
                                        }
                                    }/* i */
                                    /*
                                     * reach here if lhs and rhs are identical; subtraction will increase digit by one,
                                     * and the residue will be 0 so we are done; leave the loop with residue set to 0
                                     * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked)
                                     */
                                    thisdigit++;
                                    res.mant[have] = (byte) thisdigit;
                                    have++;
                                    var1[0] = (byte) 0; // residue to 0 [this is all we'll test]
                                    // var1len=1 -- [optimized out]
                                    break outer;
                                } while (false);
                            }/* compare */
                            /* prepare for subtraction. Estimate BA (lengths the same) */
                            ba = (int) var1[0]; // use only first digit
                        } // lengths the same
                        else {/* lhs longer than rhs */
                            /* use first two digits for estimate */
                            ba = var1[0] * 10;
                            if (var1len > 1)
                                ba = ba + var1[1];
                        }
                        /* subtraction needed; V1>=V2 */
                        mult = (ba * 10) / b2b;
                        if (mult == 0)
                            mult = 1;
                        thisdigit = thisdigit + mult;
                        // subtract; var1 reusable
                        var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true);
                        if (var1[0] != 0)
                            continue inner; // maybe another subtract needed
                        /*
                         * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than
                         * V2)
                         */
                        {
                            int $23 = var1len - 2;
                            start = 0;
                            start: for (; start <= $23; start++) {
                                if (var1[start] != 0)
                                    break start;
                                var1len--;
                            }
                        }/* start */
                        if (start == 0)
                            continue inner;
                        // shift left
                        java.lang.System.arraycopy((java.lang.Object) var1, start, (java.lang.Object) var1, 0, var1len);
                    }
                }/* inner */

                /* We have the next digit */
                if ((have != 0) | (thisdigit != 0)) { // put the digit we got
                    res.mant[have] = (byte) thisdigit;
                    have++;
                    if (have == (reqdig + 1))
                        break outer; // we have all we need
                    if (var1[0] == 0)
                        break outer; // residue now 0
                }
                /* can leave now if a scaled divide and exponent is small enough */
                if (scale >= 0)
                    if (-res.exp > scale)
                        break outer;
                /* can leave now if not Divide and no integer part left */
                if (code != 'D')
                    if (res.exp <= 0)
                        break outer;
                res.exp = res.exp - 1; // reduce the exponent
                /*
                 * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit
                 */
                var2len--;
            }
        }/* outer */

        /* here when we have finished dividing, for some reason */
        // have is the number of digits we collected in res.mant
        if (have == 0)
            have = 1; // res.mant[0] is 0; we always want a digit

        if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */
            if ((have + res.exp) > reqdig)
                throw new java.lang.ArithmeticException("Integer overflow");

            if (code == 'R') {
                do {
                    /* We were doing Remainder -- return the residue */
                    if (res.mant[0] == 0) // no integer part was found
                        return clone(lhs).finish(set, false); // .. so return lhs, canonical
                    if (var1[0] == 0)
                        return ZERO; // simple 0 residue
                    res.ind = lhs.ind; // sign is always as LHS
                    /*
                     * Calculate the exponent by subtracting the number of padding zeros we added and adding the
                     * original exponent
                     */
                    padding = ((reqdig + reqdig) + 1) - lhs.mant.length;
                    res.exp = (res.exp - padding) + lhs.exp;

                    /*
                     * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be
                     */
                    d = var1len;
                    {
                        i = d - 1;
                        i: for (; i >= 1; i--) {
                            if (!((res.exp < lhs.exp) & (res.exp < rhs.exp)))
                                break;
                            if (var1[i] != 0)
                                break i;
                            d--;
                            res.exp = res.exp + 1;
                        }
                    }/* i */
                    if (d < var1.length) {/* need to reduce */
                        newvar1 = new byte[d];
                        java.lang.System.arraycopy((java.lang.Object) var1, 0, (java.lang.Object) newvar1, 0, d); // shorten
                        var1 = newvar1;
                    }
                    res.mant = var1;
                    return res.finish(set, false);
                } while (false);
            }/* remainder */
        }

        else {/* 'D' -- no overflow check needed */
            // If there was a residue then bump the final digit (iff 0 or 5)
            // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
            // ROUND_UNNECESSARY checks (etc.) later.
            // [if we finished early, the residue will be 0]
            if (var1[0] != 0) { // residue not 0
                lasthave = res.mant[have - 1];
                if (((lasthave % 5)) == 0)
                    res.mant[have - 1] = (byte) (lasthave + 1);
            }
        }

        /* Here for Divide or Integer Divide */
        // handle scaled results first ['I' always scale 0, optional for 'D']
        if (scale >= 0) {
            do {
                // say 'scale have res.exp len' scale have res.exp res.mant.length
                if (have != res.mant.length)
                    // already padded with 0's, so just adjust exponent
                    res.exp = res.exp - ((res.mant.length - have));
                // calculate number of digits we really want [may be 0]
                actdig = res.mant.length - (-res.exp - scale);
                res.round(actdig, set.roundingMode); // round to desired length
                // This could have shifted left if round (say) 0.9->1[.0]
                // Repair if so by adding a zero and reducing exponent
                if (res.exp != -scale) {
                    res.mant = extend(res.mant, res.mant.length + 1);
                    res.exp = res.exp - 1;
                }
                return res.finish(set, true); // [strip if not PLAIN]
            } while (false);
        }/* scaled */

        // reach here only if a non-scaled
        if (have == res.mant.length) { // got digits+1 digits
            res.round(set);
            have = reqdig;
        } else {/* have<=reqdig */
            if (res.mant[0] == 0)
                return ZERO; // fastpath
            // make the mantissa truly just 'have' long
            // [we could let finish do this, during strip, if we adjusted
            // the exponent; however, truncation avoids the strip loop]
            newmant = new byte[have]; // shorten
            java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, have);
            res.mant = newmant;
        }
        return res.finish(set, true);
    }

    /* <sgml> Report a conversion exception. </sgml> */

    private void bad(char s[]) {
        throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s));
    }

    /*
     * <sgml> Report a bad argument to a method. </sgml> Arg1 is method name Arg2 is argument position Arg3 is what was
     * found
     */

    private void badarg(java.lang.String name, int pos, java.lang.String value) {
        throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " "
                + value);
    }

    /*
     * <sgml> Extend byte array to given length, padding with 0s. If no extension is required then return the same
     * array. </sgml>
     * 
     * Arg1 is the source byte array Arg2 is the new length (longer)
     */

    private static final byte[] extend(byte inarr[], int newlen) {
        byte newarr[];
        if (inarr.length == newlen)
            return inarr;
        newarr = new byte[newlen];
        java.lang.System.arraycopy((java.lang.Object) inarr, 0, (java.lang.Object) newarr, 0, inarr.length);
        // 0 padding is carried out by the JVM on allocation initialization
        return newarr;
    }

    /*
     * <sgml> Add or subtract two >=0 integers in byte arrays <p>This routine performs the calculation: <pre> C=A+(BM)
     * </pre> Where M is in the range -9 through +9 <p> If M<0 then A>=B must be true, so the result is always
     * non-negative.
     * 
     * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B,
     * or 1 longer than that (if a carry occurred).
     * 
     * A is not altered unless Arg6 is 1. B is never altered.
     * 
     * Arg1 is A Arg2 is A length to use (if longer than A, pad with 0's) Arg3 is B Arg4 is B length to use (if longer
     * than B, pad with 0's) Arg5 is M, the multiplier Arg6 is 1 if A can be used to build the result (if it fits)
     * 
     * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance
     * degradation.
     */
    // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
    // 1997.10.05 -- changed to byte arrays (from char arrays)
    // 1998.07.01 -- changed to allow destructive reuse of LHS
    // 1998.07.01 -- changed to allow virtual lengths for the arrays
    // 1998.12.29 -- use lookaside for digit/carry calculation
    // 1999.08.07 -- avoid multiply when mult=1, and make db an int
    // 1999.12.22 -- special case m=-1, also drop 0 special case
    private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) {
        int alength;
        int blength;
        int ap;
        int bp;
        int maxarr;
        byte reb[];
        boolean quickm;
        int digit;
        int op = 0;
        int dp90 = 0;
        byte newarr[];
        int i = 0;

        // We'll usually be right if we assume no carry
        alength = a.length; // physical lengths
        blength = b.length; // ..
        ap = avlen - 1; // -> final (rightmost) digit
        bp = bvlen - 1; // ..
        maxarr = bp;
        if (maxarr < ap)
            maxarr = ap;
        reb = (byte[]) null; // result byte array
        if (reuse)
            if ((maxarr + 1) == alength)
                reb = a; // OK to reuse A
        if (reb == null)
            reb = new byte[maxarr + 1]; // need new array

        quickm = false; // 1 if no multiply needed
        if (m == 1)
            quickm = true; // most common
        else if (m == (-1))
            quickm = true; // also common

        digit = 0; // digit, with carry or borrow
        {
            op = maxarr;
            op: for (; op >= 0; op--) {
                if (ap >= 0) {
                    if (ap < alength)
                        digit = digit + a[ap]; // within A
                    ap--;
                }
                if (bp >= 0) {
                    if (bp < blength) { // within B
                        if (quickm) {
                            if (m > 0)
                                digit = digit + b[bp]; // most common
                            else
                                digit = digit - b[bp]; // also common
                        } else
                            digit = digit + (b[bp] * m);
                    }
                    bp--;
                }
                /* result so far (digit) could be -90 through 99 */
                if (digit < 10)
                    if (digit >= 0) {
                        do { // 0-9
                            reb[op] = (byte) digit;
                            digit = 0; // no carry
                            continue op;
                        } while (false);
                    }/* quick */
                dp90 = digit + 90;
                reb[op] = bytedig[dp90]; // this digit
                digit = bytecar[dp90]; // carry or borrow
            }
        }/* op */

        if (digit == 0)
            return reb; // no carry
        // following line will become an Assert, later
        // if digit<0 then signal ArithmeticException("internal.error ["digit"]")

        /* We have carry -- need to make space for the extra digit */
        newarr = (byte[]) null;
        if (reuse)
            if ((maxarr + 2) == a.length)
                newarr = a; // OK to reuse A
        if (newarr == null)
            newarr = new byte[maxarr + 2];
        newarr[0] = (byte) digit; // the carried digit ..
        // .. and all the rest [use local loop for short numbers]
        if (maxarr < 10) {
            int $24 = maxarr + 1;
            i = 0;
            for (; $24 > 0; $24--, i++) {
                newarr[i + 1] = reb[i];
            }
        }/* i */
        else
            java.lang.System.arraycopy((java.lang.Object) reb, 0, (java.lang.Object) newarr, 1, maxarr + 1);
        return newarr;
    }

    /*
     * <sgml> Initializer for digit array properties (lookaside). </sgml> Returns the digit array, and initializes the
     * carry array.
     */

    private static final byte[] diginit() {
        byte work[];
        int op = 0;
        int digit = 0;
        work = new byte[(90 + 99) + 1];
        {
            op = 0;
            op: for (; op <= (90 + 99); op++) {
                digit = op - 90;
                if (digit >= 0) {
                    work[op] = (byte) (digit % 10);
                    bytecar[op] = (byte) (digit / 10); // calculate carry
                    continue op;
                }
                // borrowing...
                digit = digit + 100; // yes, this is right [consider -50]
                work[op] = (byte) (digit % 10);
                bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %]
            }
        }/* op */
        return work;
    }

    /*
     * <sgml> Create a copy of BigDecimal object for local use. <p>This does NOT make a copy of the mantissa array.
     * </sgml> Arg1 is the BigDecimal to clone (non-null)
     */

    private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) {
        com.ibm.icu.math.BigDecimal copy;
        copy = new com.ibm.icu.math.BigDecimal();
        copy.ind = dec.ind;
        copy.exp = dec.exp;
        copy.form = dec.form;
        copy.mant = dec.mant;
        return copy;
    }

    /*
     * <sgml> Check one or two numbers for lost digits. </sgml> Arg1 is RHS (or null, if none) Arg2 is current DIGITS
     * setting returns quietly or throws an exception
     */

    private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) {
        if (dig == 0)
            return; // don't check if digits=0
        // first check lhs...
        if (this.mant.length > dig)
            if ((!(allzero(this.mant, dig))))
                throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString());
        if (rhs == null)
            return; // monadic
        if (rhs.mant.length > dig)
            if ((!(allzero(rhs.mant, dig))))
                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
    }

    /*
     * <sgml> Round to specified digits, if necessary. </sgml> Arg1 is requested MathContext [with length and rounding
     * mode] returns this, for convenience
     */

    private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) {
        return round(set.digits, set.roundingMode);
    }

    /*
     * <sgml> Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when
     * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience
     * 
     * ind and exp are adjusted, but not cleared for a mantissa of zero
     * 
     * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa
     * length will be 1. </sgml>
     */

    private com.ibm.icu.math.BigDecimal round(int len, int mode) {
        int adjust;
        int sign;
        byte oldmant[];
        boolean reuse = false;
        byte first = 0;
        int increment;
        byte newmant[] = null;
        adjust = mant.length - len;
        if (adjust <= 0)
            return this; // nowt to do

        exp = exp + adjust; // exponent of result
        sign = (int) ind; // save [assumes -1, 0, 1]
        oldmant = mant; // save
        if (len > 0) {
            // remove the unwanted digits
            mant = new byte[len];
            java.lang.System.arraycopy((java.lang.Object) oldmant, 0, (java.lang.Object) mant, 0, len);
            reuse = true; // can reuse mantissa
            first = oldmant[len]; // first of discarded digits
        } else {/* len<=0 */
            mant = ZERO.mant;
            ind = iszero;
            reuse = false; // cannot reuse mantissa
            if (len == 0)
                first = oldmant[0];
            else
                first = (byte) 0; // [virtual digit]
        }

        // decide rounding adjustment depending on mode, sign, and discarded digits
        increment = 0; // bumper
        {
            do {/* select */
                if (mode == ROUND_HALF_UP) { // default first [most common]
                    if (first >= 5)
                        increment = sign;
                } else if (mode == ROUND_UNNECESSARY) { // default for setScale()
                    // discarding any non-zero digits is an error
                    if ((!(allzero(oldmant, len))))
                        throw new java.lang.ArithmeticException("Rounding necessary");
                } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down
                    if (first > 5)
                        increment = sign;
                    else if (first == 5)
                        if ((!(allzero(oldmant, len + 1))))
                            increment = sign;
                } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even
                    if (first > 5)
                        increment = sign;
                    else if (first == 5) {
                        if ((!(allzero(oldmant, len + 1))))
                            increment = sign;
                        else /* 0.5000 */
                        if ((((mant[mant.length - 1]) % 2)) == 1)
                            increment = sign;
                    }
                } else if (mode == ROUND_DOWN) {
                    // never increment
                } else if (mode == ROUND_UP) { // increment if discarded non-zero
                    if ((!(allzero(oldmant, len))))
                        increment = sign;
                } else if (mode == ROUND_CEILING) { // more positive
                    if (sign > 0)
                        if ((!(allzero(oldmant, len))))
                            increment = sign;
                } else if (mode == ROUND_FLOOR) { // more negative
                    if (sign < 0)
                        if ((!(allzero(oldmant, len))))
                            increment = sign;
                } else {
                    throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode);
                }
            } while (false);
        }/* modes */

        if (increment != 0) {
            do {
                if (ind == iszero) {
                    // we must not subtract from 0, but result is trivial anyway
                    mant = ONE.mant;
                    ind = (byte) increment;
                } else {
                    // mantissa is non-0; we can safely add or subtract 1
                    if (ind == isneg)
                        increment = -increment;
                    newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse);
                    if (newmant.length > mant.length) { // had a carry
                        // drop rightmost digit and raise exponent
                        exp++;
                        // mant is already the correct length
                        java.lang.System.arraycopy((java.lang.Object) newmant, 0, (java.lang.Object) mant, 0,
                                mant.length);
                    } else
                        mant = newmant;
                }
            } while (false);
        }/* bump */
        // rounding can increase exponent significantly
        if (exp > MaxExp)
            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
        return this;
    }

    /*
     * <sgml> Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to
     * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0
     * 
     * Arg2 may be beyond array bounds, in which case 1 is returned </sgml>
     */

    private static final boolean allzero(byte array[], int start) {
        int i = 0;
        if (start < 0)
            start = 0;
        {
            int $25 = array.length - 1;
            i = start;
            for (; i <= $25; i++) {
                if (array[i] != 0)
                    return false;
            }
        }/* i */
        return true;
    }

    /*
     * <sgml> Carry out final checks and canonicalization <p> This finishes off the current number by: 1. Rounding if
     * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping
     * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0'
     * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. </sgml> Arg1 is requested
     * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed
     * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience
     */

    private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) {
        int d = 0;
        int i = 0;
        byte newmant[] = null;
        int mag = 0;
        int sig = 0;
        /* Round if mantissa too long and digits requested */
        if (set.digits != 0)
            if (this.mant.length > set.digits)
                this.round(set);

        /*
         * If strip requested (and standard formatting), remove insignificant trailing zeros.
         */
        if (strip)
            if (set.form != com.ibm.icu.math.MathContext.PLAIN) {
                d = this.mant.length;
                /* see if we need to drop any trailing zeros */
                {
                    i = d - 1;
                    i: for (; i >= 1; i--) {
                        if (this.mant[i] != 0)
                            break i;
                        d--;
                        exp++;
                    }
                }/* i */
                if (d < this.mant.length) {/* need to reduce */
                    newmant = new byte[d];
                    java.lang.System.arraycopy((java.lang.Object) this.mant, 0, (java.lang.Object) newmant, 0, d);
                    this.mant = newmant;
                }
            }

        form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset

        /* Now check for leading- and all- zeros in mantissa */
        {
            int $26 = this.mant.length;
            i = 0;
            for (; $26 > 0; $26--, i++) {
                if (this.mant[i] != 0) {
                    // non-0 result; ind will be correct
                    // remove leading zeros [e.g., after subtract]
                    if (i > 0) {
                        do {
                            newmant = new byte[this.mant.length - i];
                            java.lang.System.arraycopy((java.lang.Object) this.mant, i, (java.lang.Object) newmant, 0,
                                    this.mant.length - i);
                            this.mant = newmant;
                        } while (false);
                    }/* delead */
                    // now determine form if not PLAIN
                    mag = exp + mant.length;
                    if (mag > 0) { // most common path
                        if (mag > set.digits)
                            if (set.digits != 0)
                                form = (byte) set.form;
                        if ((mag - 1) <= MaxExp)
                            return this; // no overflow; quick return
                    } else if (mag < (-5))
                        form = (byte) set.form;
                    /* check for overflow */
                    mag--;
                    if ((mag < MinExp) | (mag > MaxExp)) {
                        overflow: do {
                            // possible reprieve if form is engineering
                            if (form == com.ibm.icu.math.MathContext.ENGINEERING) {
                                sig = mag % 3; // leftover
                                if (sig < 0)
                                    sig = 3 + sig; // negative exponent
                                mag = mag - sig; // exponent to use
                                // 1999.06.29: second test here must be MaxExp
                                if (mag >= MinExp)
                                    if (mag <= MaxExp)
                                        break overflow;
                            }
                            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag);
                        } while (false);
                    }/* overflow */
                    return this;
                }
            }
        }/* i */

        // Drop through to here only if mantissa is all zeros
        ind = iszero;
        {/* select */
            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
                exp = 0; // standard result; go to '0'
            else if (exp > 0)
                exp = 0; // +ve exponent also goes to '0'
            else {
                // a plain number with -ve exponent; preserve and check exponent
                if (exp < MinExp)
                    throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
            }
        }
        mant = ZERO.mant; // canonical mantissa
        return this;
    }
}
