// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/* 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;

import com.ibm.icu.lang.UCharacter;

/* ------------------------------------------------------------------ */
/* BigDecimal -- Decimal arithmetic for Java                          */
/* ------------------------------------------------------------------ */
/* Copyright IBM Corporation, 1996-2016.  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.
 * </ul>
 * <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 -&gt; 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 ((!(UCharacter.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 ((!(UCharacter.isDigit(sj))))
                                bad(inchars); // not a number
                            dvalue = UCharacter.digit(sj, 10); // check base
                            if (dvalue < 0)
                                bad(inchars); // not base 10
                        } else
                            dvalue = ((sj)) - (('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 ((UCharacter.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) (((sj)) - (('0')));/* easy */
                        else {
                            dvalue = UCharacter.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) (((inchars[j])) - (('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
     */

    @Override
    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>&#42;</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
     */

    @Override
    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)
     */

    @Override
    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
     */

    @Override
    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(a, 0, 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(a, 0, 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(a, 0, 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(a, p + 2, 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
     */

    @Override
    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
     */

    @Override
    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
     */

    @Override
    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 = 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 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(res.mant, 0, 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
     */

    @Override
    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] + (('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(cmant, 0, 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(cmant, 0, 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(cmant, 0, 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(cmant, 0, rec, needsign, mag);
        rec[needsign + mag] = '.';
        java.lang.System.arraycopy(cmant, mag, 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 = 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(var1, start, 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(var1, 0, 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(res.mant, 0, 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(inarr, 0, 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 = 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 = 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(reb, 0, 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 = ind; // save [assumes -1, 0, 1]
        oldmant = mant; // save
        if (len > 0) {
            // remove the unwanted digits
            mant = new byte[len];
            java.lang.System.arraycopy(oldmant, 0, 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)) != 0)
                            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(newmant, 0, 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(this.mant, 0, 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(this.mant, i, 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;
    }
}
