Home | History | Annotate | Download | only in math
      1 /* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
      2 /* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
      3 package com.ibm.icu.math;
      4 
      5 import java.math.BigInteger;
      6 
      7 /* ------------------------------------------------------------------ */
      8 /* BigDecimal -- Decimal arithmetic for Java                          */
      9 /* ------------------------------------------------------------------ */
     10 /* Copyright IBM Corporation, 1996-2011.  All Rights Reserved.       */
     11 /*                                                                    */
     12 /* The BigDecimal class provides immutable arbitrary-precision        */
     13 /* floating point (including integer) decimal numbers.                */
     14 /*                                                                    */
     15 /* As the numbers are decimal, there is an exact correspondence       */
     16 /* between an instance of a BigDecimal object and its String          */
     17 /* representation; the BigDecimal class provides direct conversions   */
     18 /* to and from String and character array objects, and well as        */
     19 /* conversions to and from the Java primitive types (which may not    */
     20 /* be exact).                                                         */
     21 /* ------------------------------------------------------------------ */
     22 /* Notes:                                                             */
     23 /*                                                                    */
     24 /* 1. A BigDecimal object is never changed in value once constructed; */
     25 /*    this avoids the need for locking.  Note in particular that the  */
     26 /*    mantissa array may be shared between many BigDecimal objects,   */
     27 /*    so that once exposed it must not be altered.                    */
     28 /*                                                                    */
     29 /* 2. This class looks at MathContext class fields directly (for      */
     30 /*    performance).  It must not and does not change them.            */
     31 /*                                                                    */
     32 /* 3. Exponent checking is delayed until finish(), as we know         */
     33 /*    intermediate calculations cannot cause 31-bit overflow.         */
     34 /*    [This assertion depends on MAX_DIGITS in MathContext.]          */
     35 /*                                                                    */
     36 /* 4. Comments for the public API now follow the javadoc conventions. */
     37 /*    The NetRexx -comments option is used to pass these comments     */
     38 /*    through to the generated Java code (with -format, if desired).  */
     39 /*                                                                    */
     40 /* 5. System.arraycopy is faster than explicit loop as follows        */
     41 /*      Mean length 4:  equal                                         */
     42 /*      Mean length 8:  x2                                            */
     43 /*      Mean length 16: x3                                            */
     44 /*      Mean length 24: x4                                            */
     45 /*    From prior experience, we expect mean length a little below 8,  */
     46 /*    but arraycopy is still the one to use, in general, until later  */
     47 /*    measurements suggest otherwise.                                 */
     48 /*                                                                    */
     49 /* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370     */
     50 /*    assembler code implementation of the algorithms below; it is    */
     51 /*    now called IXXRCN and is available with the OS/390 and VM/ESA   */
     52 /*    operating systems.                                              */
     53 /* ------------------------------------------------------------------ */
     54 /* Change History:                                                    */
     55 /* 1997.09.02 Initial version (derived from netrexx.lang classes)     */
     56 /* 1997.09.12 Add lostDigits checking                                 */
     57 /* 1997.10.06 Change mantissa to a byte array                         */
     58 /* 1997.11.22 Rework power [did not prepare arguments, etc.]          */
     59 /* 1997.12.13 multiply did not prepare arguments                      */
     60 /* 1997.12.14 add did not prepare and align arguments correctly       */
     61 /* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle      */
     62 /* 1998.05.21 adjust remainder operator finalization                  */
     63 /* 1998.06.04 rework to pass MathContext to finish() and round()      */
     64 /* 1998.06.06 change format to use round(); support rounding modes    */
     65 /* 1998.06.25 rename to BigDecimal and begin merge                    */
     66 /*            zero can now have trailing zeros (i.e., exp\=0)         */
     67 /* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger         */
     68 /*                         unscaledValue, valueof                     */
     69 /* 1998.07.01 improve byteaddsub to allow array reuse, etc.           */
     70 /* 1998.07.01 make null testing explicit to avoid JIT bug [Win32]     */
     71 /* 1998.07.07 scaled division  [divide(BigDecimal, int, int)]         */
     72 /* 1998.07.08 setScale, faster equals                                 */
     73 /* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
     74 /* 1998.10.12 change package to com.ibm.icu.math                          */
     75 /* 1998.12.14 power operator no longer rounds RHS [to match ANSI]     */
     76 /*            add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
     77 /* 1998.12.29 improve byteaddsub by using table lookup                */
     78 /* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
     79 /* 1999.02.05 cleaner code for BigDecimal(char[])                     */
     80 /* 1999.02.06 add javadoc comments                                    */
     81 /* 1999.02.11 format() changed from 7 to 2 method form                */
     82 /* 1999.03.05 null pointer checking is no longer explicit             */
     83 /* 1999.03.05 simplify; changes from discussion with J. Bloch:        */
     84 /*            null no longer permitted for MathContext; drop boolean, */
     85 /*            byte, char, float, short constructor, deprecate double  */
     86 /*            constructor, no blanks in string constructor, add       */
     87 /*            offset and length version of char[] constructor;        */
     88 /*            add valueOf(double); drop booleanValue, charValue;      */
     89 /*            add ...Exact versions of remaining convertors           */
     90 /* 1999.03.13 add toBigIntegerExact                                   */
     91 /* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
     92 /* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic          */
     93 /* 1999.06.29 1.02 constructors should not allow exponent > 9 digits  */
     94 /* 1999.07.03 1.03 lost digits should not be checked if digits=0      */
     95 /* 1999.07.06      lost digits Exception message changed              */
     96 /* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic)             */
     97 /* 1999.07.17      improve messages from pow method                   */
     98 /* 1999.08.08      performance tweaks                                 */
     99 /* 1999.08.15      fastpath in multiply                               */
    100 /* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555]    */
    101 /* 1999.12.22 1.06 remove multiply fastpath, and improve performance  */
    102 /* 2000.01.01      copyright update [Y2K has arrived]                 */
    103 /* 2000.06.18 1.08 no longer deprecate BigDecimal(double)             */
    104 /* ------------------------------------------------------------------ */
    105 
    106 /**
    107  * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the
    108  * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format
    109  * conversions, and hashing.
    110  * <p>
    111  * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object
    112  * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from
    113  * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java
    114  * primitive types (which may not be exact) and <code>BigInteger</code>.
    115  * <p>
    116  * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number
    117  * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal
    118  * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any
    119  * operation.
    120  * <p>
    121  * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also
    122  * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br>
    123  * <i>[This URL will change.]</i>
    124  *
    125  * <h3>Operator methods</h3>
    126  * <p>
    127  * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the
    128  * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code>
    129  * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as
    130  * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9,
    131  * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point
    132  * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>.
    133  * <p>
    134  * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this
    135  * version of each method, the context settings used are <code>digits=0,
    136  * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with
    137  * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2.
    138  * <p>
    139  * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the
    140  * current object.
    141  * <p>
    142  * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The
    143  * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being
    144  * the right-hand operand.
    145  * <p>
    146  * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and
    147  * <code>extra</code> could be written as any of:
    148  * <p>
    149  * <code>
    150  *     award.add(extra)
    151  * <br>award.add(extra, MathContext.DEFAULT)
    152  * <br>award.add(extra, acontext)
    153  * </code>
    154  * <p>
    155  * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code>
    156  * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context
    157  * settings.
    158  * <p>
    159  * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by
    160  * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal
    161  * arithmetic documentation (see the URL above), but in summary:
    162  * <ul>
    163  * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the
    164  * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be
    165  * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br>
    166  * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code>
    167  * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled)
    168  * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code>
    169  * parameter). <br>
    170  * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm.
    171  * <li>
    172  * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is
    173  * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part).
    174  * <li>
    175  * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast
    176  * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros
    177  * in the fractional part of results). <br>
    178  * So, for example:
    179  * <p>
    180  * <code>
    181  *     new BigDecimal("2.40").add(     new BigDecimal("2"))      =&gt; "4.40"
    182  * <br>new BigDecimal("2.40").subtract(new BigDecimal("2"))      =&gt; "0.40"
    183  * <br>new BigDecimal("2.40").multiply(new BigDecimal("2"))      =&gt; "4.80"
    184  * <br>new BigDecimal("2.40").divide(  new BigDecimal("2"), def) =&gt; "1.2"
    185  * </code>
    186  * <p>
    187  * where the value on the right of the <code>=&gt;</code> would be the result of the operation, expressed as a
    188  * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code>
    189  * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If
    190  * necessary, trailing zeros may be easily removed using division by 1.
    191  * <li>
    192  * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of
    193  * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the
    194  * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number
    195  * will be expressed in exponential notation; thus
    196  * <p>
    197  * <code>
    198  *   new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
    199  * </code>
    200  * <p>
    201  * results in <code>1E+12</code> instead of <code>1000000000000</code>, and
    202  * <p>
    203  * <code>
    204  *   new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
    205  * </code>
    206  * <p>
    207  * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>.
    208  * <p>
    209  * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting.
    210  * <eul>
    211  * <p>
    212  * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>,
    213  * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
    214  *
    215  * @see MathContext
    216  * @author Mike Cowlishaw
    217  * @stable ICU 2.0
    218  */
    219 
    220 public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> {
    221     // private static final java.lang.String $0="BigDecimal.nrx";
    222 
    223     /* ----- Constants ----- */
    224     /* properties constant public */// useful to others
    225     /**
    226      * The <code>BigDecimal</code> constant "0".
    227      *
    228      * @see #ONE
    229      * @see #TEN
    230      * @stable ICU 2.0
    231      */
    232     public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we
    233                                                                                                       // want the int
    234                                                                                                       // constructor
    235     // .. to be able to use this, for speed
    236 
    237     /**
    238      * The <code>BigDecimal</code> constant "1".
    239      *
    240      * @see #TEN
    241      * @see #ZERO
    242      * @stable ICU 2.0
    243      */
    244     public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we
    245                                                                                                      // want the int
    246                                                                                                      // constructor
    247     // .. to be able to use this, for speed
    248 
    249     /**
    250      * The <code>BigDecimal</code> constant "10".
    251      *
    252      * @see #ONE
    253      * @see #ZERO
    254      * @stable ICU 2.0
    255      */
    256     public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10);
    257 
    258     // the rounding modes (copied here for upwards compatibility)
    259     /**
    260      * Rounding mode to round to a more positive number.
    261      *
    262      * @see MathContext#ROUND_CEILING
    263      * @stable ICU 2.0
    264      */
    265     public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING;
    266 
    267     /**
    268      * Rounding mode to round towards zero.
    269      *
    270      * @see MathContext#ROUND_DOWN
    271      * @stable ICU 2.0
    272      */
    273     public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN;
    274 
    275     /**
    276      * Rounding mode to round to a more negative number.
    277      *
    278      * @see MathContext#ROUND_FLOOR
    279      * @stable ICU 2.0
    280      */
    281     public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR;
    282 
    283     /**
    284      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down.
    285      *
    286      * @see MathContext#ROUND_HALF_DOWN
    287      * @stable ICU 2.0
    288      */
    289     public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;
    290 
    291     /**
    292      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor.
    293      *
    294      * @see MathContext#ROUND_HALF_EVEN
    295      * @stable ICU 2.0
    296      */
    297     public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;
    298 
    299     /**
    300      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up.
    301      *
    302      * @see MathContext#ROUND_HALF_UP
    303      * @stable ICU 2.0
    304      */
    305     public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP;
    306 
    307     /**
    308      * Rounding mode to assert that no rounding is necessary.
    309      *
    310      * @see MathContext#ROUND_UNNECESSARY
    311      * @stable ICU 2.0
    312      */
    313     public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;
    314 
    315     /**
    316      * Rounding mode to round away from zero.
    317      *
    318      * @see MathContext#ROUND_UP
    319      * @stable ICU 2.0
    320      */
    321     public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP;
    322 
    323     /* properties constant private */// locals
    324     private static final byte ispos = 1; // ind: indicates positive (must be 1)
    325     private static final byte iszero = 0; // ind: indicates zero (must be 0)
    326     private static final byte isneg = -1; // ind: indicates negative (must be -1)
    327     // [later could add NaN, +/- infinity, here]
    328 
    329     private static final int MinExp = -999999999; // minimum exponent allowed
    330     private static final int MaxExp = 999999999; // maximum exponent allowed
    331     private static final int MinArg = -999999999; // minimum argument integer
    332     private static final int MaxArg = 999999999; // maximum argument integer
    333 
    334     private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0,
    335             com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math
    336 
    337     /* properties constant private unused */// present but not referenced
    338     // Serialization version
    339     private static final long serialVersionUID = 8245355804974198832L;
    340 
    341     // private static final java.lang.String
    342     // copyright=" Copyright (c) IBM Corporation 1996, 2000.  All rights reserved. ";
    343 
    344     /* properties static private */
    345     // Precalculated constant arrays (used by byteaddsub)
    346     private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
    347     private static byte bytedig[] = diginit(); // next digit array
    348 
    349     /* ----- Instance properties [all private and immutable] ----- */
    350     /* properties private */
    351 
    352     /**
    353      * The indicator. This may take the values:
    354      * <ul>
    355      * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative
    356      * </ul>
    357      *
    358      * @serial
    359      */
    360     private byte ind; // assumed undefined
    361     // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
    362     // We only need two bits for this, but use a byte [also permits
    363     // smooth future extension].
    364 
    365     /**
    366      * The formatting style. This may take the values:
    367      * <ul>
    368      * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li>
    369      * MathContext.ENGINEERING -- engineering notation required
    370      * </ul>
    371      * <p>
    372      * This property is an optimization; it allows us to defer number layout until it is actually needed as a string,
    373      * hence avoiding unnecessary formatting.
    374      *
    375      * @serial
    376      */
    377     private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
    378     // We only need two bits for this, at present, but use a byte
    379     // [again, to allow for smooth future extension]
    380 
    381     /**
    382      * The value of the mantissa.
    383      * <p>
    384      * Once constructed, this may become shared between several BigDecimal objects, so must not be altered.
    385      * <p>
    386      * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9.
    387      * <p>
    388      * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a
    389      * plain number, for example, 0.000).
    390      *
    391      * @serial
    392      */
    393     private byte mant[]; // assumed null
    394 
    395     /**
    396      * The exponent.
    397      * <p>
    398      * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero.
    399      *
    400      * Note that this property can have a value less than MinExp when the mantissa has more than one digit.
    401      *
    402      * @serial
    403      */
    404     private int exp;
    405 
    406     // assumed 0
    407 
    408     /* ---------------------------------------------------------------- */
    409     /* Constructors */
    410     /* ---------------------------------------------------------------- */
    411 
    412     /**
    413      * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>.
    414      * <p>
    415      * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using
    416      * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
    417      * The parameter must not be <code>null</code>.
    418      * <p>
    419      * <i>(Note: this constructor is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class.
    420      * It would not be present in a <code>java.math</code> version.)</i>
    421      *
    422      * @param bd The <code>BigDecimal</code> to be translated.
    423      * @stable ICU 2.0
    424      */
    425 
    426     public BigDecimal(java.math.BigDecimal bd) {
    427         this(bd.toString());
    428         return;
    429     }
    430 
    431     /**
    432      * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code>, with scale 0.
    433      * <p>
    434      * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
    435      * with a scale of zero. The value of the <code>BigDecimal</code> is identical to the value of the <code>BigInteger
    436      * </code>. The parameter must not be <code>null</code>.
    437      * <p>
    438      * The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the
    439      * <code>BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
    440      *
    441      * @param bi The <code>BigInteger</code> to be converted.
    442      * @stable ICU 2.0
    443      */
    444 
    445     public BigDecimal(java.math.BigInteger bi) {
    446         this(bi.toString(10));
    447         return;
    448     }
    449 
    450     // exp remains 0
    451 
    452     /**
    453      * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code> and a scale.
    454      * <p>
    455      * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
    456      * scaled by the second parameter, which may not be negative. The value of the <code>BigDecimal</code> is the <code>
    457      * BigInteger</code> divided by ten to the power of the scale. The <code>BigInteger</code> parameter must not be
    458      * <code>null</code>.
    459      * <p>
    460      * The <code>BigDecimal</code> will contain only decimal digits, (with an embedded decimal point followed by <code>
    461      * scale</code> decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the <code>
    462      * BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
    463      *
    464      * @param bi The <code>BigInteger</code> to be converted.
    465      * @param scale The <code>int</code> specifying the scale.
    466      * @throws NumberFormatException If the scale is negative.
    467      * @stable ICU 2.0
    468      */
    469 
    470     public BigDecimal(java.math.BigInteger bi, int scale) {
    471         this(bi.toString(10));
    472         if (scale < 0)
    473             throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
    474         exp = -scale; // exponent is -scale
    475         return;
    476     }
    477 
    478     /**
    479      * Constructs a <code>BigDecimal</code> object from an array of characters.
    480      * <p>
    481      * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
    482      * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be
    483      * <code>null</code>.
    484      * <p>
    485      * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
    486      * already available in character array form.
    487      *
    488      * @param inchars The <code>char[]</code> array containing the number to be converted.
    489      * @throws NumberFormatException If the parameter is not a valid number.
    490      * @stable ICU 2.0
    491      */
    492 
    493     public BigDecimal(char inchars[]) {
    494         this(inchars, 0, inchars.length);
    495         return;
    496     }
    497 
    498     /**
    499      * Constructs a <code>BigDecimal</code> object from an array of characters.
    500      * <p>
    501      * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
    502      * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
    503      * The first parameter must not be <code>null</code>, and the subarray must be wholly contained within it.
    504      * <p>
    505      * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
    506      * already available within a character array.
    507      *
    508      * @param inchars The <code>char[]</code> array containing the number to be converted.
    509      * @param offset The <code>int</code> offset into the array of the start of the number to be converted.
    510      * @param length The <code>int</code> length of the number.
    511      * @throws NumberFormatException If the parameter is not a valid number for any reason.
    512      * @stable ICU 2.0
    513      */
    514 
    515     public BigDecimal(char inchars[], int offset, int length) {
    516         super();
    517         boolean exotic;
    518         boolean hadexp;
    519         int d;
    520         int dotoff;
    521         int last;
    522         int i = 0;
    523         char si = 0;
    524         boolean eneg = false;
    525         int k = 0;
    526         int elen = 0;
    527         int j = 0;
    528         char sj = 0;
    529         int dvalue = 0;
    530         int mag = 0;
    531         // This is the primary constructor; all incoming strings end up
    532         // here; it uses explicit (inline) parsing for speed and to avoid
    533         // generating intermediate (temporary) objects of any kind.
    534         // 1998.06.25: exponent form built only if E/e in string
    535         // 1998.06.25: trailing zeros not removed for zero
    536         // 1999.03.06: no embedded blanks; allow offset and length
    537         if (length <= 0)
    538             bad(inchars); // bad conversion (empty string)
    539         // [bad offset will raise array bounds exception]
    540 
    541         /* Handle and step past sign */
    542         ind = ispos; // assume positive
    543         if (inchars[offset] == ('-')) {
    544             length--;
    545             if (length == 0)
    546                 bad(inchars); // nothing after sign
    547             ind = isneg;
    548             offset++;
    549         } else if (inchars[offset] == ('+')) {
    550             length--;
    551             if (length == 0)
    552                 bad(inchars); // nothing after sign
    553             offset++;
    554         }
    555 
    556         /* We're at the start of the number */
    557         exotic = false; // have extra digits
    558         hadexp = false; // had explicit exponent
    559         d = 0; // count of digits found
    560         dotoff = -1; // offset where dot was found
    561         last = -1; // last character of mantissa
    562         {
    563             int $1 = length;
    564             i = offset;
    565             i: for (; $1 > 0; $1--, i++) {
    566                 si = inchars[i];
    567                 if (si >= '0') // test for Arabic digit
    568                     if (si <= '9') {
    569                         last = i;
    570                         d++; // still in mantissa
    571                         continue i;
    572                     }
    573                 if (si == '.') { // record and ignore
    574                     if (dotoff >= 0)
    575                         bad(inchars); // two dots
    576                     dotoff = i - offset; // offset into mantissa
    577                     continue i;
    578                 }
    579                 if (si != 'e')
    580                     if (si != 'E') { // expect an extra digit
    581                         if ((!(Character.isDigit(si))))
    582                             bad(inchars); // not a number
    583                         // defer the base 10 check until later to avoid extra method call
    584                         exotic = true; // will need conversion later
    585                         last = i;
    586                         d++; // still in mantissa
    587                         continue i;
    588                     }
    589                 /* Found 'e' or 'E' -- now process explicit exponent */
    590                 // 1998.07.11: sign no longer required
    591                 if ((i - offset) > (length - 2))
    592                     bad(inchars); // no room for even one digit
    593                 eneg = false;
    594                 if ((inchars[i + 1]) == ('-')) {
    595                     eneg = true;
    596                     k = i + 2;
    597                 } else if ((inchars[i + 1]) == ('+'))
    598                     k = i + 2;
    599                 else
    600                     k = i + 1;
    601                 // k is offset of first expected digit
    602                 elen = length - ((k - offset)); // possible number of digits
    603                 if ((elen == 0) | (elen > 9))
    604                     bad(inchars); // 0 or more than 9 digits
    605                 {
    606                     int $2 = elen;
    607                     j = k;
    608                     for (; $2 > 0; $2--, j++) {
    609                         sj = inchars[j];
    610                         if (sj < '0')
    611                             bad(inchars); // always bad
    612                         if (sj > '9') { // maybe an exotic digit
    613                             if ((!(Character.isDigit(sj))))
    614                                 bad(inchars); // not a number
    615                             dvalue = Character.digit(sj, 10); // check base
    616                             if (dvalue < 0)
    617                                 bad(inchars); // not base 10
    618                         } else
    619                             dvalue = ((int) (sj)) - ((int) ('0'));
    620                         exp = (exp * 10) + dvalue;
    621                     }
    622                 }/* j */
    623                 if (eneg)
    624                     exp = -exp; // was negative
    625                 hadexp = true; // remember we had one
    626                 break i; // we are done
    627             }
    628         }/* i */
    629 
    630         /* Here when all inspected */
    631         if (d == 0)
    632             bad(inchars); // no mantissa digits
    633         if (dotoff >= 0)
    634             exp = (exp + dotoff) - d; // adjust exponent if had dot
    635 
    636         /* strip leading zeros/dot (leave final if all 0's) */
    637         {
    638             int $3 = last - 1;
    639             i = offset;
    640             i: for (; i <= $3; i++) {
    641                 si = inchars[i];
    642                 if (si == '0') {
    643                     offset++;
    644                     dotoff--;
    645                     d--;
    646                 } else if (si == '.') {
    647                     offset++; // step past dot
    648                     dotoff--;
    649                 } else if (si <= '9')
    650                     break i;/* non-0 */
    651                 else {/* exotic */
    652                     if ((Character.digit(si, 10)) != 0)
    653                         break i; // non-0 or bad
    654                     // is 0 .. strip like '0'
    655                     offset++;
    656                     dotoff--;
    657                     d--;
    658                 }
    659             }
    660         }/* i */
    661 
    662         /* Create the mantissa array */
    663         mant = new byte[d]; // we know the length
    664         j = offset; // input offset
    665         if (exotic) {
    666             do { // slow: check for exotica
    667                 {
    668                     int $4 = d;
    669                     i = 0;
    670                     for (; $4 > 0; $4--, i++) {
    671                         if (i == dotoff)
    672                             j++; // at dot
    673                         sj = inchars[j];
    674                         if (sj <= '9')
    675                             mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */
    676                         else {
    677                             dvalue = Character.digit(sj, 10);
    678                             if (dvalue < 0)
    679                                 bad(inchars); // not a number after all
    680                             mant[i] = (byte) dvalue;
    681                         }
    682                         j++;
    683                     }
    684                 }/* i */
    685             } while (false);
    686         }/* exotica */
    687         else {
    688             do {
    689                 {
    690                     int $5 = d;
    691                     i = 0;
    692                     for (; $5 > 0; $5--, i++) {
    693                         if (i == dotoff)
    694                             j++;
    695                         mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0')));
    696                         j++;
    697                     }
    698                 }/* i */
    699             } while (false);
    700         }/* simple */
    701 
    702         /* Looks good. Set the sign indicator and form, as needed. */
    703         // Trailing zeros are preserved
    704         // The rule here for form is:
    705         // If no E-notation, then request plain notation
    706         // Otherwise act as though add(0,DEFAULT) and request scientific notation
    707         // [form is already PLAIN]
    708         if (mant[0] == 0) {
    709             ind = iszero; // force to show zero
    710             // negative exponent is significant (e.g., -3 for 0.000) if plain
    711             if (exp > 0)
    712                 exp = 0; // positive exponent can be ignored
    713             if (hadexp) { // zero becomes single digit from add
    714                 mant = ZERO.mant;
    715                 exp = 0;
    716             }
    717         } else { // non-zero
    718             // [ind was set earlier]
    719             // now determine form
    720             if (hadexp) {
    721                 form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC;
    722                 // 1999.06.29 check for overflow
    723                 mag = (exp + mant.length) - 1; // true exponent in scientific notation
    724                 if ((mag < MinExp) | (mag > MaxExp))
    725                     bad(inchars);
    726             }
    727         }
    728         // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
    729         return;
    730     }
    731 
    732     /**
    733      * Constructs a <code>BigDecimal</code> object directly from a <code>double</code>.
    734      * <p>
    735      * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
    736      * floating point parameter.
    737      * <p>
    738      * Note that this constructor it an exact conversion; it does not give the same result as converting <code>num
    739      * </code> to a <code>String</code> using the <code>Double.toString()</code> method and then using the
    740      * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)}
    741      * method to construct a <code>BigDecimal</code> from a <code>double</code>.
    742      *
    743      * @param num The <code>double</code> to be converted.
    744      * @throws NumberFormatException If the parameter is infinite or not a number.
    745      * @stable ICU 2.0
    746      */
    747 
    748     public BigDecimal(double num) {
    749         // 1999.03.06: use exactly the old algorithm
    750         // 2000.01.01: note that this constructor does give an exact result,
    751         // so perhaps it should not be deprecated
    752         // 2000.06.18: no longer deprecated
    753         this((new java.math.BigDecimal(num)).toString());
    754         return;
    755     }
    756 
    757     /**
    758      * Constructs a <code>BigDecimal</code> object directly from a <code>int</code>.
    759      * <p>
    760      * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 32-bit signed binary
    761      * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
    762      * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
    763      *
    764      * @param num The <code>int</code> to be converted.
    765      * @stable ICU 2.0
    766      */
    767 
    768     public BigDecimal(int num) {
    769         super();
    770         int mun;
    771         int i = 0;
    772         // We fastpath commoners
    773         if (num <= 9)
    774             if (num >= (-9)) {
    775                 do {
    776                     // very common single digit case
    777                     {/* select */
    778                         if (num == 0) {
    779                             mant = ZERO.mant;
    780                             ind = iszero;
    781                         } else if (num == 1) {
    782                             mant = ONE.mant;
    783                             ind = ispos;
    784                         } else if (num == (-1)) {
    785                             mant = ONE.mant;
    786                             ind = isneg;
    787                         } else {
    788                             {
    789                                 mant = new byte[1];
    790                                 if (num > 0) {
    791                                     mant[0] = (byte) num;
    792                                     ind = ispos;
    793                                 } else { // num<-1
    794                                     mant[0] = (byte) -num;
    795                                     ind = isneg;
    796                                 }
    797                             }
    798                         }
    799                     }
    800                     return;
    801                 } while (false);
    802             }/* singledigit */
    803 
    804         /* We work on negative numbers so we handle the most negative number */
    805         if (num > 0) {
    806             ind = ispos;
    807             num = -num;
    808         } else
    809             ind = isneg;/* negative */// [0 case already handled]
    810         // [it is quicker, here, to pre-calculate the length with
    811         // one loop, then allocate exactly the right length of byte array,
    812         // then re-fill it with another loop]
    813         mun = num; // working copy
    814         {
    815             i = 9;
    816             i: for (;; i--) {
    817                 mun = mun / 10;
    818                 if (mun == 0)
    819                     break i;
    820             }
    821         }/* i */
    822         // i is the position of the leftmost digit placed
    823         mant = new byte[10 - i];
    824         {
    825             i = (10 - i) - 1;
    826             i: for (;; i--) {
    827                 mant[i] = (byte) -(((byte) (num % 10)));
    828                 num = num / 10;
    829                 if (num == 0)
    830                     break i;
    831             }
    832         }/* i */
    833         return;
    834     }
    835 
    836     /**
    837      * Constructs a <code>BigDecimal</code> object directly from a <code>long</code>.
    838      * <p>
    839      * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
    840      * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
    841      * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
    842      *
    843      * @param num The <code>long</code> to be converted.
    844      * @stable ICU 2.0
    845      */
    846 
    847     public BigDecimal(long num) {
    848         super();
    849         long mun;
    850         int i = 0;
    851         // Not really worth fastpathing commoners in this constructor [also,
    852         // we use this to construct the static constants].
    853         // This is much faster than: this(String.valueOf(num).toCharArray())
    854         /* We work on negative num so we handle the most negative number */
    855         if (num > 0) {
    856             ind = ispos;
    857             num = -num;
    858         } else if (num == 0)
    859             ind = iszero;
    860         else
    861             ind = isneg;/* negative */
    862         mun = num;
    863         {
    864             i = 18;
    865             i: for (;; i--) {
    866                 mun = mun / 10;
    867                 if (mun == 0)
    868                     break i;
    869             }
    870         }/* i */
    871         // i is the position of the leftmost digit placed
    872         mant = new byte[19 - i];
    873         {
    874             i = (19 - i) - 1;
    875             i: for (;; i--) {
    876                 mant[i] = (byte) -(((byte) (num % 10)));
    877                 num = num / 10;
    878                 if (num == 0)
    879                     break i;
    880             }
    881         }/* i */
    882         return;
    883     }
    884 
    885     /**
    886      * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
    887      * <p>
    888      * Constructs a <code>BigDecimal</code> from the parameter, which must not be <code>null</code> and must represent a
    889      * valid <i>number</i>, as described formally in the documentation referred to {@link BigDecimal above}.
    890      * <p>
    891      * In summary, numbers in <code>String</code> form must have at least one digit, may have a leading sign, may have a
    892      * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks.
    893      * <p>
    894      * Some valid strings from which a <code>BigDecimal</code> might be constructed are:
    895      *
    896      * <pre>
    897      *
    898      * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
    899      * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
    900      * Exponential notation
    901      *
    902      * </pre>
    903      * <p>
    904      * (Exponential notation means that the number includes an optional sign and a power of ten following an
    905      * '</code>E</code>' that indicates how the decimal point will be shifted. Thus the <code>"4E+9"</code> above is
    906      * just a short way of writing <code>4000000000</code>, and the <code>"0.73e-7"</code> is short for <code>
    907      * 0.000000073</code>.)
    908      * <p>
    909      * The <code>BigDecimal</code> constructed from the String is in a standard form, with no blanks, as though the
    910      * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string
    911      * uses exponential notation (that is, includes an <code>e</code> or an <code>E</code>), then the <code>BigDecimal
    912      * </code> number will be expressed in scientific notation (where the power of ten is adjusted so there is a single
    913      * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as
    914      * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must
    915      * fit in nine digits both before and after it is expressed in scientific notation.
    916      * <p>
    917      * Any digits in the parameter must be decimal; that is, <code>Character.digit(c, 10)</code> (where </code>c</code>
    918      * is the character in question) would not return -1.
    919      *
    920      * @param string The <code>String</code> to be converted.
    921      * @throws NumberFormatException If the parameter is not a valid number.
    922      * @stable ICU 2.0
    923      */
    924 
    925     public BigDecimal(java.lang.String string) {
    926         this(string.toCharArray(), 0, string.length());
    927         return;
    928     }
    929 
    930     /* <sgml> Make a default BigDecimal object for local use. </sgml> */
    931 
    932     private BigDecimal() {
    933         super();
    934         return;
    935     }
    936 
    937     /* ---------------------------------------------------------------- */
    938     /* Operator methods [methods which take a context parameter] */
    939     /* ---------------------------------------------------------------- */
    940 
    941     /**
    942      * Returns a plain <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
    943      * <p>
    944      * The same as {@link #abs(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
    945      * <p>
    946      * The length of the decimal part (the scale) of the result will be <code>this.scale()</code>
    947      *
    948      * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
    949      * @stable ICU 2.0
    950      */
    951 
    952     public com.ibm.icu.math.BigDecimal abs() {
    953         return this.abs(plainMC);
    954     }
    955 
    956     /**
    957      * Returns a <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
    958      * <p>
    959      * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method
    960      * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)}
    961      * method with the same parameter is returned.
    962      *
    963      * @param set The <code>MathContext</code> arithmetic settings.
    964      * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
    965      * @stable ICU 2.0
    966      */
    967 
    968     public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) {
    969         if (this.ind == isneg)
    970             return this.negate(set);
    971         return this.plus(set);
    972     }
    973 
    974     /**
    975      * Returns a plain <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
    976      * <p>
    977      * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
    978      * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
    979      * <p>
    980      * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
    981      *
    982      * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
    983      * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
    984      * @stable ICU 2.0
    985      */
    986 
    987     public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) {
    988         return this.add(rhs, plainMC);
    989     }
    990 
    991     /**
    992      * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
    993      * <p>
    994      * Implements the addition (<b><code>+</code></b>) operator (as defined in the decimal documentation, see
    995      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
    996      *
    997      * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
    998      * @param set The <code>MathContext</code> arithmetic settings.
    999      * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>.
   1000      * @stable ICU 2.0
   1001      */
   1002 
   1003     public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1004         com.ibm.icu.math.BigDecimal lhs;
   1005         int reqdig;
   1006         com.ibm.icu.math.BigDecimal res;
   1007         byte usel[];
   1008         int usellen;
   1009         byte user[];
   1010         int userlen;
   1011         int newlen = 0;
   1012         int tlen = 0;
   1013         int mult = 0;
   1014         byte t[] = null;
   1015         int ia = 0;
   1016         int ib = 0;
   1017         int ea = 0;
   1018         int eb = 0;
   1019         byte ca = 0;
   1020         byte cb = 0;
   1021         /* determine requested digits and form */
   1022         if (set.lostDigits)
   1023             checkdigits(rhs, set.digits);
   1024         lhs = this; // name for clarity and proxy
   1025 
   1026         /* Quick exit for add floating 0 */
   1027         // plus() will optimize to return same object if possible
   1028         if (lhs.ind == 0)
   1029             if (set.form != com.ibm.icu.math.MathContext.PLAIN)
   1030                 return rhs.plus(set);
   1031         if (rhs.ind == 0)
   1032             if (set.form != com.ibm.icu.math.MathContext.PLAIN)
   1033                 return lhs.plus(set);
   1034 
   1035         /* Prepare numbers (round, unless unlimited precision) */
   1036         reqdig = set.digits; // local copy (heavily used)
   1037         if (reqdig > 0) {
   1038             if (lhs.mant.length > reqdig)
   1039                 lhs = clone(lhs).round(set);
   1040             if (rhs.mant.length > reqdig)
   1041                 rhs = clone(rhs).round(set);
   1042             // [we could reuse the new LHS for result in this case]
   1043         }
   1044 
   1045         res = new com.ibm.icu.math.BigDecimal(); // build result here
   1046 
   1047         /*
   1048          * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much
   1049          * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to
   1050          * DIGITS trailing zeros].
   1051          */
   1052         // Note sign may be 0 if digits (reqdig) is 0
   1053         // usel and user will be the byte arrays passed to the adder; we'll
   1054         // use them on all paths except quick exits
   1055         usel = lhs.mant;
   1056         usellen = lhs.mant.length;
   1057         user = rhs.mant;
   1058         userlen = rhs.mant.length;
   1059         {
   1060             do {/* select */
   1061                 if (lhs.exp == rhs.exp) {/* no padding needed */
   1062                     // This is the most common, and fastest, path
   1063                     res.exp = lhs.exp;
   1064                 } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs
   1065                     newlen = (usellen + lhs.exp) - rhs.exp;
   1066                     /*
   1067                      * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot
   1068                      * affect answer, so we only need to pad up to a length of DIGITS+1.
   1069                      */
   1070                     if (newlen >= ((userlen + reqdig) + 1))
   1071                         if (reqdig > 0) {
   1072                             // LHS is sufficient
   1073                             res.mant = usel;
   1074                             res.exp = lhs.exp;
   1075                             res.ind = lhs.ind;
   1076                             if (usellen < reqdig) { // need 0 padding
   1077                                 res.mant = extend(lhs.mant, reqdig);
   1078                                 res.exp = res.exp - ((reqdig - usellen));
   1079                             }
   1080                             return res.finish(set, false);
   1081                         }
   1082                     // RHS may affect result
   1083                     res.exp = rhs.exp; // expected final exponent
   1084                     if (newlen > (reqdig + 1))
   1085                         if (reqdig > 0) {
   1086                             // LHS will be max; RHS truncated
   1087                             tlen = (newlen - reqdig) - 1; // truncation length
   1088                             userlen = userlen - tlen;
   1089                             res.exp = res.exp + tlen;
   1090                             newlen = reqdig + 1;
   1091                         }
   1092                     if (newlen > usellen)
   1093                         usellen = newlen; // need to pad LHS
   1094                 } else { // need to pad rhs and/or truncate lhs
   1095                     newlen = (userlen + rhs.exp) - lhs.exp;
   1096                     if (newlen >= ((usellen + reqdig) + 1))
   1097                         if (reqdig > 0) {
   1098                             // RHS is sufficient
   1099                             res.mant = user;
   1100                             res.exp = rhs.exp;
   1101                             res.ind = rhs.ind;
   1102                             if (userlen < reqdig) { // need 0 padding
   1103                                 res.mant = extend(rhs.mant, reqdig);
   1104                                 res.exp = res.exp - ((reqdig - userlen));
   1105                             }
   1106                             return res.finish(set, false);
   1107                         }
   1108                     // LHS may affect result
   1109                     res.exp = lhs.exp; // expected final exponent
   1110                     if (newlen > (reqdig + 1))
   1111                         if (reqdig > 0) {
   1112                             // RHS will be max; LHS truncated
   1113                             tlen = (newlen - reqdig) - 1; // truncation length
   1114                             usellen = usellen - tlen;
   1115                             res.exp = res.exp + tlen;
   1116                             newlen = reqdig + 1;
   1117                         }
   1118                     if (newlen > userlen)
   1119                         userlen = newlen; // need to pad RHS
   1120                 }
   1121             } while (false);
   1122         }/* padder */
   1123 
   1124         /* OK, we have aligned mantissas. Now add or subtract. */
   1125         // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
   1126         // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
   1127         // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
   1128         if (lhs.ind == iszero)
   1129             res.ind = ispos;
   1130         else
   1131             res.ind = lhs.ind; // likely sign, all paths
   1132         if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative
   1133             mult = 1;
   1134         else {
   1135             do { // different signs, so subtraction is needed
   1136                 mult = -1; // will cause subtract
   1137                 /*
   1138                  * Before we can subtract we must determine which is the larger, as our add/subtract routine only
   1139                  * handles non-negative results so we may need to swap the operands.
   1140                  */
   1141                 {
   1142                     do {/* select */
   1143                         if (rhs.ind == iszero) {
   1144                             // original A bigger
   1145                         } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger
   1146                             t = usel;
   1147                             usel = user;
   1148                             user = t; // swap
   1149                             tlen = usellen;
   1150                             usellen = userlen;
   1151                             userlen = tlen; // ..
   1152                             res.ind = (byte) -res.ind; // and set sign
   1153                         } else if (usellen > userlen) {
   1154                             // original A bigger
   1155                         } else {
   1156                             {/* logical lengths the same */// need compare
   1157                                 /* may still need to swap: compare the strings */
   1158                                 ia = 0;
   1159                                 ib = 0;
   1160                                 ea = usel.length - 1;
   1161                                 eb = user.length - 1;
   1162                                 {
   1163                                     compare: for (;;) {
   1164                                         if (ia <= ea)
   1165                                             ca = usel[ia];
   1166                                         else {
   1167                                             if (ib > eb) {/* identical */
   1168                                                 if (set.form != com.ibm.icu.math.MathContext.PLAIN)
   1169                                                     return ZERO;
   1170                                                 // [if PLAIN we must do the subtract, in case of 0.000 results]
   1171                                                 break compare;
   1172                                             }
   1173                                             ca = (byte) 0;
   1174                                         }
   1175                                         if (ib <= eb)
   1176                                             cb = user[ib];
   1177                                         else
   1178                                             cb = (byte) 0;
   1179                                         if (ca != cb) {
   1180                                             if (ca < cb) {/* swap needed */
   1181                                                 t = usel;
   1182                                                 usel = user;
   1183                                                 user = t; // swap
   1184                                                 tlen = usellen;
   1185                                                 usellen = userlen;
   1186                                                 userlen = tlen; // ..
   1187                                                 res.ind = (byte) -res.ind;
   1188                                             }
   1189                                             break compare;
   1190                                         }
   1191                                         /* mantissas the same, so far */
   1192                                         ia++;
   1193                                         ib++;
   1194                                     }
   1195                                 }/* compare */
   1196                             } // lengths the same
   1197                         }
   1198                     } while (false);
   1199                 }/* swaptest */
   1200             } while (false);
   1201         }/* signdiff */
   1202 
   1203         /* here, A is > B if subtracting */
   1204         // add [A+B*1] or subtract [A+(B*-1)]
   1205         res.mant = byteaddsub(usel, usellen, user, userlen, mult, false);
   1206         // [reuse possible only after chop; accounting makes not worthwhile]
   1207 
   1208         // Finish() rounds before stripping leading 0's, then sets form, etc.
   1209         return res.finish(set, false);
   1210     }
   1211 
   1212     /**
   1213      * Compares this <code>BigDecimal</code> to another, using unlimited precision.
   1214      * <p>
   1215      * The same as {@link #compareTo(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
   1216      * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1217      *
   1218      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1219      * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
   1220      *         or greater than <code>rhs</code>.
   1221      * @stable ICU 2.0
   1222      */
   1223 
   1224     public int compareTo(com.ibm.icu.math.BigDecimal rhs) {
   1225         return this.compareTo(rhs, plainMC);
   1226     }
   1227 
   1228     /**
   1229      * Compares this <code>BigDecimal</code> to another.
   1230      * <p>
   1231      * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}),
   1232      * and returns a result of type <code>int</code>.
   1233      * <p>
   1234      * The result will be:
   1235      * <table cellpadding=2>
   1236      * <tr>
   1237      * <td align=right><b>-1</b></td> <td>if the current object is less than the first parameter</td>
   1238      * </tr>
   1239      * <tr>
   1240      * <td align=right><b>0</b></td> <td>if the current object is equal to the first parameter</td>
   1241      * </tr>
   1242      * <tr>
   1243      * <td align=right><b>1</b></td> <td>if the current object is greater than the first parameter.</td>
   1244      * </tr>
   1245      * </table>
   1246      * <p>
   1247      * A {@link #compareTo(BigDecimal)} method is also provided.
   1248      *
   1249      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1250      * @param set The <code>MathContext</code> arithmetic settings.
   1251      * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
   1252      *         or greater than <code>rhs</code>.
   1253      * @stable ICU 2.0
   1254      */
   1255 
   1256     public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1257         int thislength = 0;
   1258         int i = 0;
   1259         com.ibm.icu.math.BigDecimal newrhs;
   1260         // rhs=null will raise NullPointerException, as per Comparable interface
   1261         if (set.lostDigits)
   1262             checkdigits(rhs, set.digits);
   1263         // [add will recheck in slowpath cases .. but would report -rhs]
   1264         if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) {
   1265             /* sign & exponent the same [very common] */
   1266             thislength = this.mant.length;
   1267             if (thislength < rhs.mant.length)
   1268                 return (byte) -this.ind;
   1269             if (thislength > rhs.mant.length)
   1270                 return this.ind;
   1271             /*
   1272              * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very
   1273              * unusual]
   1274              */
   1275             if ((thislength <= set.digits) | (set.digits == 0)) {
   1276                 {
   1277                     int $6 = thislength;
   1278                     i = 0;
   1279                     for (; $6 > 0; $6--, i++) {
   1280                         if (this.mant[i] < rhs.mant[i])
   1281                             return (byte) -this.ind;
   1282                         if (this.mant[i] > rhs.mant[i])
   1283                             return this.ind;
   1284                     }
   1285                 }/* i */
   1286                 return 0; // identical
   1287             }
   1288             /* drop through for full comparison */
   1289         } else {
   1290             /* More fastpaths possible */
   1291             if (this.ind < rhs.ind)
   1292                 return -1;
   1293             if (this.ind > rhs.ind)
   1294                 return 1;
   1295         }
   1296         /* carry out a subtract to make the comparison */
   1297         newrhs = clone(rhs); // safe copy
   1298         newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
   1299         return this.add(newrhs, set).ind; // add, and return sign of result
   1300     }
   1301 
   1302     /**
   1303      * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
   1304      * <p>
   1305      * The same as {@link #divide(BigDecimal, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1306      * rounding mode is {@link MathContext#ROUND_HALF_UP}.
   1307      *
   1308      * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
   1309      * the latter were formatted without exponential notation.
   1310      *
   1311      * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
   1312      * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
   1313      * @throws ArithmeticException If <code>rhs</code> is zero.
   1314      * @stable ICU 2.0
   1315      */
   1316 
   1317     public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) {
   1318         return this.dodivide('D', rhs, plainMC, -1);
   1319     }
   1320 
   1321     /**
   1322      * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
   1323      * rounding mode.
   1324      * <p>
   1325      * The same as {@link #divide(BigDecimal, int, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1326      * second parameter is <code>this.scale()</code>, and the third is <code>round</code>.
   1327      * <p>
   1328      * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current
   1329      * object, if the latter were formatted without exponential notation.
   1330      * <p>
   1331      *
   1332      * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
   1333      * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
   1334      * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
   1335      *         the specified rounding mode.
   1336      * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
   1337      * @throws ArithmeticException if <code>rhs</code> is zero.
   1338      * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>this.scale()</code> is insufficient to represent the result exactly.
   1339      * @stable ICU 2.0
   1340      */
   1341 
   1342     public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) {
   1343         com.ibm.icu.math.MathContext set;
   1344         set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round,
   1345                                                                                                      // too]
   1346         return this.dodivide('D', rhs, set, -1); // take scale from LHS
   1347     }
   1348 
   1349     /**
   1350      * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
   1351      * given scale and rounding mode.
   1352      * <p>
   1353      * The same as {@link #divide(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
   1354      * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>, except that the length of the decimal part (the
   1355      * scale) to be used for the result is explicit rather than being taken from <code>this</code>.
   1356      * <p>
   1357      * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
   1358      * the latter were formatted without exponential notation.
   1359      * <p>
   1360      *
   1361      * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
   1362      * @param scale The <code>int</code> scale to be used for the result.
   1363      * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
   1364      * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
   1365      *         the specified rounding mode.
   1366      * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
   1367      * @throws ArithmeticException if <code>rhs</code> is zero.
   1368      * @throws ArithmeticException if <code>scale</code> is negative.
   1369      * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>scale</code> is insufficient
   1370      *             to represent the result exactly.
   1371      * @stable ICU 2.0
   1372      */
   1373 
   1374     public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) {
   1375         com.ibm.icu.math.MathContext set;
   1376         if (scale < 0)
   1377             throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
   1378         set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round]
   1379         return this.dodivide('D', rhs, set, scale);
   1380     }
   1381 
   1382     /**
   1383      * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
   1384      * <p>
   1385      * Implements the division (<b><code>/</code></b>) operator (as defined in the decimal documentation, see
   1386      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1387      *
   1388      * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
   1389      * @param set The <code>MathContext</code> arithmetic settings.
   1390      * @return A <code>BigDecimal</code> whose value is <code>this/rhs</code>.
   1391      * @throws ArithmeticException if <code>rhs</code> is zero.
   1392      * @stable ICU 2.0
   1393      */
   1394 
   1395     public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1396         return this.dodivide('D', rhs, set, -1);
   1397     }
   1398 
   1399     /**
   1400      * Returns a plain <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
   1401      * <p>
   1402      * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs
   1403      * </code>, and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1404      *
   1405      * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
   1406      * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
   1407      * @throws ArithmeticException if <code>rhs</code> is zero.
   1408      * @stable ICU 2.0
   1409      */
   1410 
   1411     public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) {
   1412         // scale 0 to drop .000 when plain
   1413         return this.dodivide('I', rhs, plainMC, 0);
   1414     }
   1415 
   1416     /**
   1417      * Returns a <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
   1418      * <p>
   1419      * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class
   1420      * header}), and returns the result as a <code>BigDecimal</code> object.
   1421      *
   1422      * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
   1423      * @param set The <code>MathContext</code> arithmetic settings.
   1424      * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
   1425      * @throws ArithmeticException if <code>rhs</code> is zero.
   1426      * @throws ArithmeticException if the result will not fit in the number of digits specified for the context.
   1427      * @stable ICU 2.0
   1428      */
   1429 
   1430     public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1431         // scale 0 to drop .000 when plain
   1432         return this.dodivide('I', rhs, set, 0);
   1433     }
   1434 
   1435     /**
   1436      * Returns a plain <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
   1437      * <p>
   1438      * The same as {@link #max(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1439      * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1440      *
   1441      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1442      * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
   1443      * @stable ICU 2.0
   1444      */
   1445 
   1446     public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) {
   1447         return this.max(rhs, plainMC);
   1448     }
   1449 
   1450     /**
   1451      * Returns a <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
   1452      * <p>
   1453      * Returns the larger of the current object and the first parameter.
   1454      * <p>
   1455      * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>1
   1456      * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
   1457      * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
   1458      * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
   1459      * parameter) is returned.
   1460      *
   1461      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1462      * @param set The <code>MathContext</code> arithmetic settings.
   1463      * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
   1464      * @stable ICU 2.0
   1465      */
   1466 
   1467     public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1468         if ((this.compareTo(rhs, set)) >= 0)
   1469             return this.plus(set);
   1470         else
   1471             return rhs.plus(set);
   1472     }
   1473 
   1474     /**
   1475      * Returns a plain <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
   1476      * <p>
   1477      * The same as {@link #min(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1478      * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1479      *
   1480      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1481      * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
   1482      * @stable ICU 2.0
   1483      */
   1484 
   1485     public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) {
   1486         return this.min(rhs, plainMC);
   1487     }
   1488 
   1489     /**
   1490      * Returns a <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
   1491      * <p>
   1492      * Returns the smaller of the current object and the first parameter.
   1493      * <p>
   1494      * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>-1
   1495      * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
   1496      * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
   1497      * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
   1498      * parameter) is returned.
   1499      *
   1500      * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
   1501      * @param set The <code>MathContext</code> arithmetic settings.
   1502      * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
   1503      * @stable ICU 2.0
   1504      */
   1505 
   1506     public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1507         if ((this.compareTo(rhs, set)) <= 0)
   1508             return this.plus(set);
   1509         else
   1510             return rhs.plus(set);
   1511     }
   1512 
   1513     /**
   1514      * Returns a plain <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
   1515      * <p>
   1516      * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1517      * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1518      * <p>
   1519      * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they
   1520      * were formatted without exponential notation.
   1521      *
   1522      * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
   1523      * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
   1524      * @stable ICU 2.0
   1525      */
   1526 
   1527     public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) {
   1528         return this.multiply(rhs, plainMC);
   1529     }
   1530 
   1531     /**
   1532      * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
   1533      * <p>
   1534      * Implements the multiplication (<b><code> </code></b>) operator (as defined in the decimal documentation, see
   1535      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1536      *
   1537      * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
   1538      * @param set The <code>MathContext</code> arithmetic settings.
   1539      * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>.
   1540      * @stable ICU 2.0
   1541      */
   1542 
   1543     public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1544         com.ibm.icu.math.BigDecimal lhs;
   1545         int padding;
   1546         int reqdig;
   1547         byte multer[] = null;
   1548         byte multand[] = null;
   1549         int multandlen;
   1550         int acclen = 0;
   1551         com.ibm.icu.math.BigDecimal res;
   1552         byte acc[];
   1553         int n = 0;
   1554         byte mult = 0;
   1555         if (set.lostDigits)
   1556             checkdigits(rhs, set.digits);
   1557         lhs = this; // name for clarity and proxy
   1558 
   1559         /* Prepare numbers (truncate, unless unlimited precision) */
   1560         padding = 0; // trailing 0's to add
   1561         reqdig = set.digits; // local copy
   1562         if (reqdig > 0) {
   1563             if (lhs.mant.length > reqdig)
   1564                 lhs = clone(lhs).round(set);
   1565             if (rhs.mant.length > reqdig)
   1566                 rhs = clone(rhs).round(set);
   1567             // [we could reuse the new LHS for result in this case]
   1568         } else {/* unlimited */
   1569             // fixed point arithmetic will want every trailing 0; we add these
   1570             // after the calculation rather than before, for speed.
   1571             if (lhs.exp > 0)
   1572                 padding = padding + lhs.exp;
   1573             if (rhs.exp > 0)
   1574                 padding = padding + rhs.exp;
   1575         }
   1576 
   1577         // For best speed, as in DMSRCN, we use the shorter number as the
   1578         // multiplier and the longer as the multiplicand.
   1579         // 1999.12.22: We used to special case when the result would fit in
   1580         // a long, but with Java 1.3 this gave no advantage.
   1581         if (lhs.mant.length < rhs.mant.length) {
   1582             multer = lhs.mant;
   1583             multand = rhs.mant;
   1584         } else {
   1585             multer = rhs.mant;
   1586             multand = lhs.mant;
   1587         }
   1588 
   1589         /* Calculate how long result byte array will be */
   1590         multandlen = (multer.length + multand.length) - 1; // effective length
   1591         // optimize for 75% of the cases where a carry is expected...
   1592         if ((multer[0] * multand[0]) > 9)
   1593             acclen = multandlen + 1;
   1594         else
   1595             acclen = multandlen;
   1596 
   1597         /* Now the main long multiplication loop */
   1598         res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
   1599         acc = new byte[acclen]; // accumulator, all zeros
   1600         // 1998.07.01: calculate from left to right so that accumulator goes
   1601         // to likely final length on first addition; this avoids a one-digit
   1602         // extension (and object allocation) each time around the loop.
   1603         // Initial number therefore has virtual zeros added to right.
   1604         {
   1605             int $7 = multer.length;
   1606             n = 0;
   1607             for (; $7 > 0; $7--, n++) {
   1608                 mult = multer[n];
   1609                 if (mult != 0) { // [optimization]
   1610                     // accumulate [accumulator is reusable array]
   1611                     acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true);
   1612                 }
   1613                 // divide multiplicand by 10 for next digit to right
   1614                 multandlen--; // 'virtual length'
   1615             }
   1616         }/* n */
   1617 
   1618         res.ind = (byte) (lhs.ind * rhs.ind); // final sign
   1619         res.exp = (lhs.exp + rhs.exp) - padding; // final exponent
   1620         // [overflow is checked by finish]
   1621 
   1622         /* add trailing zeros to the result, if necessary */
   1623         if (padding == 0)
   1624             res.mant = acc;
   1625         else
   1626             res.mant = extend(acc, acc.length + padding); // add trailing 0s
   1627         return res.finish(set, false);
   1628     }
   1629 
   1630     /**
   1631      * Returns a plain <code>BigDecimal</code> whose value is <code>-this</code>.
   1632      * <p>
   1633      * The same as {@link #negate(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>
   1634      * .
   1635      * <p>
   1636      * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
   1637      *
   1638      *
   1639      * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
   1640      * @stable ICU 2.0
   1641      */
   1642 
   1643     public com.ibm.icu.math.BigDecimal negate() {
   1644         return this.negate(plainMC);
   1645     }
   1646 
   1647     /**
   1648      * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
   1649      * <p>
   1650      * Implements the negation (Prefix <b><code>-</code></b>) operator (as defined in the decimal documentation, see
   1651      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1652      *
   1653      * @param set The <code>MathContext</code> arithmetic settings.
   1654      * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
   1655      * @stable ICU 2.0
   1656      */
   1657 
   1658     public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) {
   1659         com.ibm.icu.math.BigDecimal res;
   1660         // Originally called minus(), changed to matched Java precedents
   1661         // This simply clones, flips the sign, and possibly rounds
   1662         if (set.lostDigits)
   1663             checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
   1664         res = clone(this); // safe copy
   1665         res.ind = (byte) -res.ind;
   1666         return res.finish(set, false);
   1667     }
   1668 
   1669     /**
   1670      * Returns a plain <code>BigDecimal</code> whose value is <code>+this</code>. Note that <code>this</code> is not
   1671      * necessarily a plain <code>BigDecimal</code>, but the result will always be.
   1672      * <p>
   1673      * The same as {@link #plus(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1674      * <p>
   1675      * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
   1676      *
   1677      * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
   1678      * @stable ICU 2.0
   1679      */
   1680 
   1681     public com.ibm.icu.math.BigDecimal plus() {
   1682         return this.plus(plainMC);
   1683     }
   1684 
   1685     /**
   1686      * Returns a <code>BigDecimal</code> whose value is <code>+this</code>.
   1687      * <p>
   1688      * Implements the plus (Prefix <b><code>+</code></b>) operator (as defined in the decimal documentation, see
   1689      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1690      * <p>
   1691      * This method is useful for rounding or otherwise applying a context to a decimal value.
   1692      *
   1693      * @param set The <code>MathContext</code> arithmetic settings.
   1694      * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
   1695      * @stable ICU 2.0
   1696      */
   1697 
   1698     public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) {
   1699         // This clones and forces the result to the new settings
   1700         // May return same object
   1701         if (set.lostDigits)
   1702             checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
   1703         // Optimization: returns same object for some common cases
   1704         if (set.form == com.ibm.icu.math.MathContext.PLAIN)
   1705             if (this.form == com.ibm.icu.math.MathContext.PLAIN) {
   1706                 if (this.mant.length <= set.digits)
   1707                     return this;
   1708                 if (set.digits == 0)
   1709                     return this;
   1710             }
   1711         return clone(this).finish(set, false);
   1712     }
   1713 
   1714     /**
   1715      * Returns a plain <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
   1716      * <p>
   1717      * The same as {@link #pow(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
   1718      * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1719      * <p>
   1720      * The parameter is the power to which the <code>this</code> will be raised; it must be in the range 0 through
   1721      * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so
   1722      * they should not be used as a test for a whole number.
   1723      * <p>
   1724      * In addition, the power must not be negative, as no <code>MathContext</code> is used and so the result would then
   1725      * always be 0.
   1726      *
   1727      * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
   1728      * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
   1729      * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
   1730      * @stable ICU 2.0
   1731      */
   1732 
   1733     public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) {
   1734         return this.pow(rhs, plainMC);
   1735     }
   1736 
   1737     // The name for this method is inherited from the precedent set by the
   1738     // BigInteger and Math classes.
   1739 
   1740     /**
   1741      * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
   1742      * <p>
   1743      * Implements the power (<b><code> </code></b>) operator (as defined in the decimal documentation, see
   1744      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1745      * <p>
   1746      * The first parameter is the power to which the <code>this</code> will be raised; it must be in the range
   1747      * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed
   1748      * in the future, so they should not be used as a test for a whole number.
   1749      * <p>
   1750      * If the <code>digits</code> setting of the <code>MathContext</code> parameter is 0, the power must be zero or
   1751      * positive.
   1752      *
   1753      * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
   1754      * @param set The <code>MathContext</code> arithmetic settings.
   1755      * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>.
   1756      * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
   1757      * @stable ICU 2.0
   1758      */
   1759 
   1760     public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1761         int n;
   1762         com.ibm.icu.math.BigDecimal lhs;
   1763         int reqdig;
   1764         int workdigits = 0;
   1765         int L = 0;
   1766         com.ibm.icu.math.MathContext workset;
   1767         com.ibm.icu.math.BigDecimal res;
   1768         boolean seenbit;
   1769         int i = 0;
   1770         if (set.lostDigits)
   1771             checkdigits(rhs, set.digits);
   1772         n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules
   1773         lhs = this; // clarified name
   1774 
   1775         reqdig = set.digits; // local copy (heavily used)
   1776         if (reqdig == 0) {
   1777             if (rhs.ind == isneg)
   1778                 throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString());
   1779             workdigits = 0;
   1780         } else {/* non-0 digits */
   1781             if ((rhs.mant.length + rhs.exp) > reqdig)
   1782                 throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
   1783 
   1784             /* Round the lhs to DIGITS if need be */
   1785             if (lhs.mant.length > reqdig)
   1786                 lhs = clone(lhs).round(set);
   1787 
   1788             /* L for precision calculation [see ANSI X3.274-1996] */
   1789             L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp
   1790             workdigits = (reqdig + L) + 1; // calculate the working DIGITS
   1791         }
   1792 
   1793         /* Create a copy of set for working settings */
   1794         // Note: no need to check for lostDigits again.
   1795         // 1999.07.17 Note: this construction must follow RHS check
   1796         workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode);
   1797 
   1798         res = ONE; // accumulator
   1799         if (n == 0)
   1800             return res; // x**0 == 1
   1801         if (n < 0)
   1802             n = -n; // [rhs.ind records the sign]
   1803         seenbit = false; // set once we've seen a 1-bit
   1804         {
   1805             i = 1;
   1806             i: for (;; i++) { // for each bit [top bit ignored]
   1807                 n = n + n; // shift left 1 bit
   1808                 if (n < 0) { // top bit is set
   1809                     seenbit = true; // OK, we're off
   1810                     res = res.multiply(lhs, workset); // acc=acc*x
   1811                 }
   1812                 if (i == 31)
   1813                     break i; // that was the last bit
   1814                 if ((!seenbit))
   1815                     continue i; // we don't have to square 1
   1816                 res = res.multiply(res, workset); // acc=acc*acc [square]
   1817             }
   1818         }/* i */// 32 bits
   1819         if (rhs.ind < 0) // was a **-n [hence digits>0]
   1820             res = ONE.divide(res, workset); // .. so acc=1/acc
   1821         return res.finish(set, true); // round and strip [original digits]
   1822     }
   1823 
   1824     /**
   1825      * Returns a plain <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
   1826      * arithmetic.
   1827      * <p>
   1828      * The same as {@link #remainder(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
   1829      * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1830      * <p>
   1831      * This is not the modulo operator -- the result may be negative.
   1832      *
   1833      * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
   1834      * @return A <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
   1835      *         arithmetic.
   1836      * @throws ArithmeticException if <code>rhs</code> is zero.
   1837      * @stable ICU 2.0
   1838      */
   1839 
   1840     public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) {
   1841         return this.dodivide('R', rhs, plainMC, -1);
   1842     }
   1843 
   1844     /**
   1845      * Returns a <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>.
   1846      * <p>
   1847      * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}),
   1848      * and returns the result as a <code>BigDecimal</code> object.
   1849      * <p>
   1850      * This is not the modulo operator -- the result may be negative.
   1851      *
   1852      * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
   1853      * @param set The <code>MathContext</code> arithmetic settings.
   1854      * @return A <code>BigDecimal</code> whose value is the remainder of <code>this+rhs</code>.
   1855      * @throws ArithmeticException if <code>rhs</code> is zero.
   1856      * @throws ArithmeticException  if the integer part of the result will not fit in the number of digits specified for the context.
   1857      * @stable ICU 2.0
   1858      */
   1859 
   1860     public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1861         return this.dodivide('R', rhs, set, -1);
   1862     }
   1863 
   1864     /**
   1865      * Returns a plain <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
   1866      * <p>
   1867      * The same as {@link #subtract(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
   1868      * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
   1869      * <p>
   1870      * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
   1871      *
   1872      * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
   1873      * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
   1874      * @stable ICU 2.0
   1875      */
   1876 
   1877     public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) {
   1878         return this.subtract(rhs, plainMC);
   1879     }
   1880 
   1881     /**
   1882      * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
   1883      * <p>
   1884      * Implements the subtraction (<b><code>-</code></b>) operator (as defined in the decimal documentation, see
   1885      * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
   1886      *
   1887      * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
   1888      * @param set The <code>MathContext</code> arithmetic settings.
   1889      * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>.
   1890      * @stable ICU 2.0
   1891      */
   1892 
   1893     public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
   1894         com.ibm.icu.math.BigDecimal newrhs;
   1895         if (set.lostDigits)
   1896             checkdigits(rhs, set.digits);
   1897         // [add will recheck .. but would report -rhs]
   1898         /* carry out the subtraction */
   1899         // we could fastpath -0, but it is too rare.
   1900         newrhs = clone(rhs); // safe copy
   1901         newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
   1902         return this.add(newrhs, set); // arithmetic
   1903     }
   1904 
   1905     /* ---------------------------------------------------------------- */
   1906     /* Other methods */
   1907     /* ---------------------------------------------------------------- */
   1908 
   1909     /**
   1910      * Converts this <code>BigDecimal</code> to a <code>byte</code>. If the <code>BigDecimal</code> has a non-zero
   1911      * decimal part or is out of the possible range for a <code>byte</code> (8-bit signed integer) result then an <code>
   1912      * ArithmeticException</code> is thrown.
   1913      *
   1914      * @return A <code>byte</code> equal in value to <code>this</code>.
   1915      * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>byte</code>.
   1916      * @stable ICU 2.0
   1917      */
   1918 
   1919     public byte byteValueExact() {
   1920         int num;
   1921         num = this.intValueExact(); // will check decimal part too
   1922         if ((num > 127) | (num < (-128)))
   1923             throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   1924         return (byte) num;
   1925     }
   1926 
   1927     /**
   1928      * Converts this <code>BigDecimal</code> to a <code>double</code>. If the <code>BigDecimal</code> is out of the
   1929      * possible range for a <code>double</code> (64-bit signed floating point) result then an <code>ArithmeticException
   1930      * </code> is thrown.
   1931      * <p>
   1932      * The double produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
   1933      * then converting it using the <code>Double(String)</code> constructor; this can result in values of <code>
   1934      * Double.NEGATIVE_INFINITY</code> or <code>Double.POSITIVE_INFINITY</code>.
   1935      *
   1936      * @return A <code>double</code> corresponding to <code>this</code>.
   1937      * @stable ICU 2.0
   1938      */
   1939 
   1940     public double doubleValue() {
   1941         // We go via a String [as does BigDecimal in JDK 1.2]
   1942         // Next line could possibly raise NumberFormatException
   1943         return java.lang.Double.valueOf(this.toString()).doubleValue();
   1944     }
   1945 
   1946     /**
   1947      * Compares this <code>BigDecimal</code> with <code>rhs</code> for equality.
   1948      * <p>
   1949      * If the parameter is <code>null</code>, or is not an instance of the BigDecimal type, or is not exactly equal to
   1950      * the current <code>BigDecimal</code> object, then <i>false</i> is returned. Otherwise, <i>true</i> is returned.
   1951      * <p>
   1952      * "Exactly equal", here, means that the <code>String</code> representations of the <code>BigDecimal</code> numbers
   1953      * are identical (they have the same characters in the same sequence).
   1954      * <p>
   1955      * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons.
   1956      *
   1957      * @param obj The <code>Object</code> for the right hand side of the comparison.
   1958      * @return A <code>boolean</code> whose value <i>true</i> if and only if the operands have identical string
   1959      *         representations.
   1960      * @throws ClassCastException if <code>rhs</code> cannot be cast to a <code>BigDecimal</code> object.
   1961      * @stable ICU 2.0
   1962      * @see #compareTo(BigDecimal)
   1963      * @see #compareTo(BigDecimal, MathContext)
   1964      */
   1965 
   1966     public boolean equals(java.lang.Object obj) {
   1967         com.ibm.icu.math.BigDecimal rhs;
   1968         int i = 0;
   1969         char lca[] = null;
   1970         char rca[] = null;
   1971         // We are equal iff toString of both are exactly the same
   1972         if (obj == null)
   1973             return false; // not equal
   1974         if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
   1975             return false; // not a decimal
   1976         rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work
   1977         if (this.ind != rhs.ind)
   1978             return false; // different signs never match
   1979         if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form))
   1980 
   1981         { // mantissas say all
   1982             // here with equal-length byte arrays to compare
   1983             {
   1984                 int $8 = this.mant.length;
   1985                 i = 0;
   1986                 for (; $8 > 0; $8--, i++) {
   1987                     if (this.mant[i] != rhs.mant[i])
   1988                         return false;
   1989                 }
   1990             }/* i */
   1991         } else { // need proper layout
   1992             lca = this.layout(); // layout to character array
   1993             rca = rhs.layout();
   1994             if (lca.length != rca.length)
   1995                 return false; // mismatch
   1996             // here with equal-length character arrays to compare
   1997             {
   1998                 int $9 = lca.length;
   1999                 i = 0;
   2000                 for (; $9 > 0; $9--, i++) {
   2001                     if (lca[i] != rca[i])
   2002                         return false;
   2003                 }
   2004             }/* i */
   2005         }
   2006         return true; // arrays have identical content
   2007     }
   2008 
   2009     /**
   2010      * Converts this <code>BigDecimal</code> to a <code>float</code>. If the <code>BigDecimal</code> is out of the
   2011      * possible range for a <code>float</code> (32-bit signed floating point) result then an <code>ArithmeticException
   2012      * </code> is thrown.
   2013      * <p>
   2014      * The float produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
   2015      * then converting it using the <code>Float(String)</code> constructor; this can result in values of <code>
   2016      * Float.NEGATIVE_INFINITY</code> or <code>Float.POSITIVE_INFINITY</code>.
   2017      *
   2018      * @return A <code>float</code> corresponding to <code>this</code>.
   2019      * @stable ICU 2.0
   2020      */
   2021 
   2022     public float floatValue() {
   2023         return java.lang.Float.valueOf(this.toString()).floatValue();
   2024     }
   2025 
   2026     /**
   2027      * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters.
   2028      * <p>
   2029      * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
   2030      * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
   2031      * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
   2032      * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
   2033      * </i>
   2034      * <p>
   2035      * The parameters, for both forms of the <code>format</code> method are all of type <code>int</code>. A value of -1
   2036      * for any parameter indicates that the default action or value for that parameter should be used.
   2037      * <p>
   2038      * The parameters, <code>before</code> and <code>after</code>, specify the number of characters to be used for the
   2039      * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter
   2040      * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed
   2041      * for that part.
   2042      * <p>
   2043      * <code>before</code> must be a positive number; if it is larger than is needed to contain the integer part, that
   2044      * part is padded on the left with blanks to the requested length. If <code>before</code> is not large enough to
   2045      * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown.
   2046      * <p>
   2047      * <code>after</code> must be a non-negative number; if it is not the same size as the decimal part of the number,
   2048      * the number will be rounded (or extended with zeros) to fit. Specifying 0 for <code>after</code> will cause the
   2049      * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method
   2050      * will be the default, <code>MathContext.ROUND_HALF_UP</code>.
   2051      * <p>
   2052      * Other rounding methods, and the use of exponential notation, can be selected by using
   2053      * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect
   2054      * as using the six-parameter form with the final four parameters all being -1.
   2055      *
   2056      * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as are needed'.
   2057      * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as are needed'.
   2058      * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified parameters
   2059      * @throws ArithmeticException if the number cannot be laid out as requested.
   2060      * @throws IllegalArgumentException if a parameter is out of range.
   2061      * @stable ICU 2.0
   2062      * @see #toString
   2063      * @see #toCharArray
   2064      */
   2065 
   2066     public java.lang.String format(int before, int after) {
   2067         return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP);
   2068     }
   2069 
   2070     /**
   2071      * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters and
   2072      * allowing exponential notation.
   2073      * <p>
   2074      * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
   2075      * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
   2076      * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
   2077      * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
   2078      * </i>
   2079      * <p>
   2080      * The parameters are all of type <code>int</code>. A value of -1 for any parameter indicates that the default
   2081      * action or value for that parameter should be used.
   2082      * <p>
   2083      * The first two parameters (<code>before</code> and <code>after</code>) specify the number of characters to be used
   2084      * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If
   2085      * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many
   2086      * as are needed for that part.
   2087      * <p>
   2088      * The remaining parameters control the use of exponential notation and rounding. Three (<code>explaces</code>,
   2089      * <code>exdigits</code>, and <code>exform</code>) control the exponent part of the result. As before, the default
   2090      * action for any of these parameters may be selected by using the value -1.
   2091      * <p>
   2092      * <code>explaces</code> must be a positive number; it sets the number of places (digits after the sign of the
   2093      * exponent) to be used for any exponent part, the default (when <code>explaces</code> is -1) being to use as many
   2094      * as are needed. If <code>explaces</code> is not -1, space is always reserved for an exponent; if one is not needed
   2095      * (for example, if the exponent will be 0) then <code>explaces</code>+2 blanks are appended to the result. <!--
   2096      * (This preserves vertical alignment of similarly formatted numbers in a monospace font.) --> If <code>explaces
   2097      * </code> is not -1 and is not large enough to contain the exponent, an exception is thrown.
   2098      * <p>
   2099      * <code>exdigits</code> sets the trigger point for use of exponential notation. If, before any rounding, the number
   2100      * of places needed before the decimal point exceeds <code>exdigits</code>, or if the absolute value of the result
   2101      * is less than <code>0.000001</code>, then exponential form will be used, provided that <code>exdigits</code> was
   2102      * specified. When <code>exdigits</code> is -1, exponential notation will never be used. If 0 is specified for
   2103      * <code>exdigits</code>, exponential notation is always used unless the exponent would be 0.
   2104      * <p>
   2105      * <code>exform</code> sets the form for exponential notation (if needed). It may be either
   2106      * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested,
   2107      * up to three digits (plus sign, if negative) may be needed for the integer part of the result (<code>before</code>
   2108      * ). Otherwise, only one digit (plus sign, if negative) is needed.
   2109      * <p>
   2110      * Finally, the sixth argument, <code>exround</code>, selects the rounding algorithm to be used, and must be one of
   2111      * the values indicated by a public constant in the {@link MathContext} class whose name starts with <code>ROUND_
   2112      * </code>. The default (<code>ROUND_HALF_UP</code>) may also be selected by using the value -1, as before.
   2113      * <p>
   2114      * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be used to detect whether non-zero digits are
   2115      * discarded -- if <code>exround</code> has this value than if non-zero digits would be discarded (rounded) during
   2116      * formatting then an <code>ArithmeticException</code> is thrown.
   2117      *
   2118      * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as
   2119      *            are needed'.
   2120      * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as
   2121      *            are needed'.
   2122      * @param explaces The <code>int</code> specifying the number of places to be used for any exponent. Use -1 for 'as many
   2123      *            as are needed'.
   2124      * @param exdigits The <code>int</code> specifying the trigger (digits before the decimal point) which if exceeded causes
   2125      *            exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation
   2126      *            (no exponential notation).
   2127      * @param exformint The <code>int</code> specifying the form of exponential notation to be used (
   2128      *            {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}).
   2129      * @param exround The <code>int</code> specifying the rounding mode to use. Use -1 for the default,
   2130      *            {@link MathContext#ROUND_HALF_UP}.
   2131      * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified
   2132      *         parameters
   2133      * @throws ArithmeticException if the number cannot be laid out as requested.
   2134      * @throws IllegalArgumentException if a parameter is out of range.
   2135      * @see #toString
   2136      * @see #toCharArray
   2137      * @stable ICU 2.0
   2138      */
   2139 
   2140     public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) {
   2141         com.ibm.icu.math.BigDecimal num;
   2142         int mag = 0;
   2143         int thisafter = 0;
   2144         int lead = 0;
   2145         byte newmant[] = null;
   2146         int chop = 0;
   2147         int need = 0;
   2148         int oldexp = 0;
   2149         char a[];
   2150         int p = 0;
   2151         char newa[] = null;
   2152         int i = 0;
   2153         int places = 0;
   2154 
   2155         /* Check arguments */
   2156         if ((before < (-1)) | (before == 0))
   2157             badarg("format", 1, java.lang.String.valueOf(before));
   2158         if (after < (-1))
   2159             badarg("format", 2, java.lang.String.valueOf(after));
   2160         if ((explaces < (-1)) | (explaces == 0))
   2161             badarg("format", 3, java.lang.String.valueOf(explaces));
   2162         if (exdigits < (-1))
   2163             badarg("format", 4, java.lang.String.valueOf(explaces));
   2164         {/* select */
   2165             if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) {
   2166             } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) {
   2167             } else if (exformint == (-1))
   2168                 exformint = com.ibm.icu.math.MathContext.SCIENTIFIC;
   2169             // note PLAIN isn't allowed
   2170             else {
   2171                 badarg("format", 5, java.lang.String.valueOf(exformint));
   2172             }
   2173         }
   2174         // checking the rounding mode is done by trying to construct a
   2175         // MathContext object with that mode; it will fail if bad
   2176         if (exround != ROUND_HALF_UP) {
   2177             try { // if non-default...
   2178                 if (exround == (-1))
   2179                     exround = ROUND_HALF_UP;
   2180                 else
   2181                     new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround);
   2182             } catch (java.lang.IllegalArgumentException $10) {
   2183                 badarg("format", 6, java.lang.String.valueOf(exround));
   2184             }
   2185         }
   2186 
   2187         num = clone(this); // make private copy
   2188 
   2189         /*
   2190          * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0]
   2191          * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two]
   2192          * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified
   2193          */
   2194 
   2195         /* determine form */
   2196         {
   2197             do {/* select */
   2198                 if (exdigits == (-1))
   2199                     num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
   2200                 else if (num.ind == iszero)
   2201                     num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
   2202                 else {
   2203                     // determine whether triggers
   2204                     mag = num.exp + num.mant.length;
   2205                     if (mag > exdigits)
   2206                         num.form = (byte) exformint;
   2207                     else if (mag < (-5))
   2208                         num.form = (byte) exformint;
   2209                     else
   2210                         num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
   2211                 }
   2212             } while (false);
   2213         }/* setform */
   2214 
   2215         /*
   2216          * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform
   2217          * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific).
   2218          */
   2219         if (after >= 0) {
   2220             setafter: for (;;) {
   2221                 // calculate the current after-length
   2222                 {/* select */
   2223                     if (num.form == com.ibm.icu.math.MathContext.PLAIN)
   2224                         thisafter = -num.exp; // has decimal part
   2225                     else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC)
   2226                         thisafter = num.mant.length - 1;
   2227                     else { // engineering
   2228                         lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use
   2229                         if (lead < 0)
   2230                             lead = 3 + lead; // negative exponent case
   2231                         lead++; // number of leading digits
   2232                         if (lead >= num.mant.length)
   2233                             thisafter = 0;
   2234                         else
   2235                             thisafter = num.mant.length - lead;
   2236                     }
   2237                 }
   2238                 if (thisafter == after)
   2239                     break setafter; // we're in luck
   2240                 if (thisafter < after) { // need added trailing zeros
   2241                     // [thisafter can be negative]
   2242                     newmant = extend(num.mant, (num.mant.length + after) - thisafter);
   2243                     num.mant = newmant;
   2244                     num.exp = num.exp - ((after - thisafter)); // adjust exponent
   2245                     if (num.exp < MinExp)
   2246                         throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp);
   2247                     break setafter;
   2248                 }
   2249                 // We have too many digits after the decimal point; this could
   2250                 // cause a carry, which could change the mantissa...
   2251                 // Watch out for implied leading zeros in PLAIN case
   2252                 chop = thisafter - after; // digits to lop [is >0]
   2253                 if (chop > num.mant.length) { // all digits go, no chance of carry
   2254                     // carry on with zero
   2255                     num.mant = ZERO.mant;
   2256                     num.ind = iszero;
   2257                     num.exp = 0;
   2258                     continue setafter; // recheck: we may need trailing zeros
   2259                 }
   2260                 // we have a digit to inspect from existing mantissa
   2261                 // round the number as required
   2262                 need = num.mant.length - chop; // digits to end up with [may be 0]
   2263                 oldexp = num.exp; // save old exponent
   2264                 num.round(need, exround);
   2265                 // if the exponent grew by more than the digits we chopped, then
   2266                 // we must have had a carry, so will need to recheck the layout
   2267                 if ((num.exp - oldexp) == chop)
   2268                     break setafter; // number did not have carry
   2269                 // mantissa got extended .. so go around and check again
   2270             }
   2271         }/* setafter */
   2272 
   2273         a = num.layout(); // lay out, with exponent if required, etc.
   2274 
   2275         /* Here we have laid-out number in 'a' */
   2276         // now apply 'before' and 'explaces' as needed
   2277         if (before > 0) {
   2278             // look for '.' or 'E'
   2279             {
   2280                 int $11 = a.length;
   2281                 p = 0;
   2282                 p: for (; $11 > 0; $11--, p++) {
   2283                     if (a[p] == '.')
   2284                         break p;
   2285                     if (a[p] == 'E')
   2286                         break p;
   2287                 }
   2288             }/* p */
   2289             // p is now offset of '.', 'E', or character after end of array
   2290             // that is, the current length of before part
   2291             if (p > before)
   2292                 badarg("format", 1, java.lang.String.valueOf(before)); // won't fit
   2293             if (p < before) { // need leading blanks
   2294                 newa = new char[(a.length + before) - p];
   2295                 {
   2296                     int $12 = before - p;
   2297                     i = 0;
   2298                     for (; $12 > 0; $12--, i++) {
   2299                         newa[i] = ' ';
   2300                     }
   2301                 }/* i */
   2302                 java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, i, a.length);
   2303                 a = newa;
   2304             }
   2305             // [if p=before then it's just the right length]
   2306         }
   2307 
   2308         if (explaces > 0) {
   2309             // look for 'E' [cannot be at offset 0]
   2310             {
   2311                 int $13 = a.length - 1;
   2312                 p = a.length - 1;
   2313                 p: for (; $13 > 0; $13--, p--) {
   2314                     if (a[p] == 'E')
   2315                         break p;
   2316                 }
   2317             }/* p */
   2318             // p is now offset of 'E', or 0
   2319             if (p == 0) { // no E part; add trailing blanks
   2320                 newa = new char[(a.length + explaces) + 2];
   2321                 java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, a.length);
   2322                 {
   2323                     int $14 = explaces + 2;
   2324                     i = a.length;
   2325                     for (; $14 > 0; $14--, i++) {
   2326                         newa[i] = ' ';
   2327                     }
   2328                 }/* i */
   2329                 a = newa;
   2330             } else {/* found E */// may need to insert zeros
   2331                 places = (a.length - p) - 2; // number so far
   2332                 if (places > explaces)
   2333                     badarg("format", 3, java.lang.String.valueOf(explaces));
   2334                 if (places < explaces) { // need to insert zeros
   2335                     newa = new char[(a.length + explaces) - places];
   2336                     java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, p + 2); // through E
   2337                                                                                                             // and sign
   2338                     {
   2339                         int $15 = explaces - places;
   2340                         i = p + 2;
   2341                         for (; $15 > 0; $15--, i++) {
   2342                             newa[i] = '0';
   2343                         }
   2344                     }/* i */
   2345                     java.lang.System.arraycopy((java.lang.Object) a, p + 2, (java.lang.Object) newa, i, places); // remainder
   2346                                                                                                                  // of
   2347                                                                                                                  // exponent
   2348                     a = newa;
   2349                 }
   2350                 // [if places=explaces then it's just the right length]
   2351             }
   2352         }
   2353         return new java.lang.String(a);
   2354     }
   2355 
   2356     /**
   2357      * Returns the hashcode for this <code>BigDecimal</code>. This hashcode is suitable for use by the <code>
   2358      * java.util.Hashtable</code> class.
   2359      * <p>
   2360      * Note that two <code>BigDecimal</code> objects are only guaranteed to produce the same hashcode if they are
   2361      * exactly equal (that is, the <code>String</code> representations of the <code>BigDecimal</code> numbers are
   2362      * identical -- they have the same characters in the same sequence).
   2363      *
   2364      * @return An <code>int</code> that is the hashcode for <code>this</code>.
   2365      * @stable ICU 2.0
   2366      */
   2367 
   2368     public int hashCode() {
   2369         // Maybe calculate ourselves, later. If so, note that there can be
   2370         // more than one internal representation for a given toString() result.
   2371         return this.toString().hashCode();
   2372     }
   2373 
   2374     /**
   2375      * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
   2376      * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for an <code>int</code>
   2377      * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be
   2378      * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact}
   2379      * method.
   2380      *
   2381      * @return An <code>int</code> converted from <code>this</code>, truncated and decapitated if necessary.
   2382      * @stable ICU 2.0
   2383      */
   2384 
   2385     public int intValue() {
   2386         return toBigInteger().intValue();
   2387     }
   2388 
   2389     /**
   2390      * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
   2391      * decimal part or is out of the possible range for an <code>int</code> (32-bit signed integer) result then an
   2392      * <code>ArithmeticException</code> is thrown.
   2393      *
   2394      * @return An <code>int</code> equal in value to <code>this</code>.
   2395      * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in an <code>int</code>.
   2396      * @stable ICU 2.0
   2397      */
   2398 
   2399     public int intValueExact() {
   2400         int lodigit;
   2401         int useexp = 0;
   2402         int result;
   2403         int i = 0;
   2404         int topdig = 0;
   2405         // This does not use longValueExact() as the latter can be much
   2406         // slower.
   2407         // intcheck (from pow) relies on this to check decimal part
   2408         if (ind == iszero)
   2409             return 0; // easy, and quite common
   2410         /* test and drop any trailing decimal part */
   2411         lodigit = mant.length - 1;
   2412         if (exp < 0) {
   2413             lodigit = lodigit + exp; // reduces by -(-exp)
   2414             /* all decimal places must be 0 */
   2415             if ((!(allzero(mant, lodigit + 1))))
   2416                 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
   2417             if (lodigit < 0)
   2418                 return 0; // -1<this<1
   2419             useexp = 0;
   2420         } else {/* >=0 */
   2421             if ((exp + lodigit) > 9) // early exit
   2422                 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   2423             useexp = exp;
   2424         }
   2425         /* convert the mantissa to binary, inline for speed */
   2426         result = 0;
   2427         {
   2428             int $16 = lodigit + useexp;
   2429             i = 0;
   2430             for (; i <= $16; i++) {
   2431                 result = result * 10;
   2432                 if (i <= lodigit)
   2433                     result = result + mant[i];
   2434             }
   2435         }/* i */
   2436 
   2437         /* Now, if the risky length, check for overflow */
   2438         if ((lodigit + useexp) == 9) {
   2439             // note we cannot just test for -ve result, as overflow can move a
   2440             // zero into the top bit [consider 5555555555]
   2441             topdig = result / 1000000000; // get top digit, preserving sign
   2442             if (topdig != mant[0]) { // digit must match and be positive
   2443                 // except in the special case ...
   2444                 if (result == java.lang.Integer.MIN_VALUE) // looks like the special
   2445                     if (ind == isneg) // really was negative
   2446                         if (mant[0] == 2)
   2447                             return result; // really had top digit 2
   2448                 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   2449             }
   2450         }
   2451 
   2452         /* Looks good */
   2453         if (ind == ispos)
   2454             return result;
   2455         return -result;
   2456     }
   2457 
   2458     /**
   2459      * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
   2460      * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for a <code>long</code>
   2461      * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be
   2462      * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact}
   2463      * method.
   2464      *
   2465      * @return A <code>long</code> converted from <code>this</code>, truncated and decapitated if necessary.
   2466      * @stable ICU 2.0
   2467      */
   2468 
   2469     public long longValue() {
   2470         return toBigInteger().longValue();
   2471     }
   2472 
   2473     /**
   2474      * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
   2475      * decimal part or is out of the possible range for a <code>long</code> (64-bit signed integer) result then an
   2476      * <code>ArithmeticException</code> is thrown.
   2477      *
   2478      * @return A <code>long</code> equal in value to <code>this</code>.
   2479      * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>long</code>.
   2480      * @stable ICU 2.0
   2481      */
   2482 
   2483     public long longValueExact() {
   2484         int lodigit;
   2485         int cstart = 0;
   2486         int useexp = 0;
   2487         long result;
   2488         int i = 0;
   2489         long topdig = 0;
   2490         // Identical to intValueExact except for result=long, and exp>=20 test
   2491         if (ind == 0)
   2492             return 0; // easy, and quite common
   2493         lodigit = mant.length - 1; // last included digit
   2494         if (exp < 0) {
   2495             lodigit = lodigit + exp; // -(-exp)
   2496             /* all decimal places must be 0 */
   2497             if (lodigit < 0)
   2498                 cstart = 0;
   2499             else
   2500                 cstart = lodigit + 1;
   2501             if ((!(allzero(mant, cstart))))
   2502                 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
   2503             if (lodigit < 0)
   2504                 return 0; // -1<this<1
   2505             useexp = 0;
   2506         } else {/* >=0 */
   2507             if ((exp + mant.length) > 18) // early exit
   2508                 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   2509             useexp = exp;
   2510         }
   2511 
   2512         /* convert the mantissa to binary, inline for speed */
   2513         // note that we could safely use the 'test for wrap to negative'
   2514         // algorithm here, but instead we parallel the intValueExact
   2515         // algorithm for ease of checking and maintenance.
   2516         result = (long) 0;
   2517         {
   2518             int $17 = lodigit + useexp;
   2519             i = 0;
   2520             for (; i <= $17; i++) {
   2521                 result = result * 10;
   2522                 if (i <= lodigit)
   2523                     result = result + mant[i];
   2524             }
   2525         }/* i */
   2526 
   2527         /* Now, if the risky length, check for overflow */
   2528         if ((lodigit + useexp) == 18) {
   2529             topdig = result / 1000000000000000000L; // get top digit, preserving sign
   2530             if (topdig != mant[0]) { // digit must match and be positive
   2531                 // except in the special case ...
   2532                 if (result == java.lang.Long.MIN_VALUE) // looks like the special
   2533                     if (ind == isneg) // really was negative
   2534                         if (mant[0] == 9)
   2535                             return result; // really had top digit 9
   2536                 throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   2537             }
   2538         }
   2539 
   2540         /* Looks good */
   2541         if (ind == ispos)
   2542             return result;
   2543         return -result;
   2544     }
   2545 
   2546     /**
   2547      * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the left by a specified number of
   2548      * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
   2549      * if <code>n</code> is 0 or positive, the number returned is given by:
   2550      * <p>
   2551      * <code> this.multiply(TEN.pow(new BigDecimal(-n))) </code>
   2552      * <p>
   2553      * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointRight(-n)
   2554      * </code>.
   2555      *
   2556      * @param n The <code>int</code> specifying the number of places to move the decimal point leftwards.
   2557      * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
   2558      *         places to the left.
   2559      * @stable ICU 2.0
   2560      */
   2561 
   2562     public com.ibm.icu.math.BigDecimal movePointLeft(int n) {
   2563         com.ibm.icu.math.BigDecimal res;
   2564         // very little point in optimizing for shift of 0
   2565         res = clone(this);
   2566         res.exp = res.exp - n;
   2567         return res.finish(plainMC, false); // finish sets form and checks exponent
   2568     }
   2569 
   2570     /**
   2571      * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the right by a specified number of
   2572      * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
   2573      * if <code>n</code> is 0 or positive, the number returned is given by:
   2574      * <p>
   2575      * <code> this.multiply(TEN.pow(new BigDecimal(n))) </code>
   2576      * <p>
   2577      * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointLeft(-n)
   2578      * </code>.
   2579      *
   2580      * @param n The <code>int</code> specifying the number of places to move the decimal point rightwards.
   2581      * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
   2582      *         places to the right.
   2583      * @stable ICU 2.0
   2584      */
   2585 
   2586     public com.ibm.icu.math.BigDecimal movePointRight(int n) {
   2587         com.ibm.icu.math.BigDecimal res;
   2588         res = clone(this);
   2589         res.exp = res.exp + n;
   2590         return res.finish(plainMC, false);
   2591     }
   2592 
   2593     /**
   2594      * Returns the scale of this <code>BigDecimal</code>. Returns a non-negative <code>int</code> which is the scale of
   2595      * the number. The scale is the number of digits in the decimal part of the number if the number were formatted
   2596      * without exponential notation.
   2597      *
   2598      * @return An <code>int</code> whose value is the scale of this <code>BigDecimal</code>.
   2599      * @stable ICU 2.0
   2600      */
   2601 
   2602     public int scale() {
   2603         if (exp >= 0)
   2604             return 0; // scale can never be negative
   2605         return -exp;
   2606     }
   2607 
   2608     /**
   2609      * Returns a plain <code>BigDecimal</code> with a given scale.
   2610      * <p>
   2611      * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
   2612      * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
   2613      * <p>
   2614      * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
   2615      * trailing digits will be removed, and in this case an <code>ArithmeticException</code> is thrown if any discarded
   2616      * digits are non-zero.
   2617      * <p>
   2618      * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is <code>
   2619      * MathContext.ROUND_UNNECESSARY</code>.
   2620      *
   2621      * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
   2622      * @return A plain <code>BigDecimal</code> with the given scale.
   2623      * @throws ArithmeticException if <code>scale</code> is negative.
   2624      * @throws ArithmeticException if reducing scale would discard non-zero digits.
   2625      * @stable ICU 2.0
   2626      */
   2627 
   2628     public com.ibm.icu.math.BigDecimal setScale(int scale) {
   2629         return setScale(scale, ROUND_UNNECESSARY);
   2630     }
   2631 
   2632     /**
   2633      * Returns a plain <code>BigDecimal</code> with a given scale.
   2634      * <p>
   2635      * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
   2636      * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
   2637      * <p>
   2638      * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
   2639      * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the
   2640      * remaining digits are affected by a carry. In this case, an <code>IllegalArgumentException</code> is thrown if
   2641      * <code>round</code> is not a valid rounding mode.
   2642      * <p>
   2643      * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, an <code>ArithmeticException</code> is
   2644      * thrown if any discarded digits are non-zero.
   2645      *
   2646      * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
   2647      * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
   2648      * @return A plain <code>BigDecimal</code> with the given scale.
   2649      * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
   2650      * @throws ArithmeticException if <code>scale</code> is negative.
   2651      * @throws ArithmeticException if <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, and reducing scale would discard
   2652      *             non-zero digits.
   2653      * @stable ICU 2.0
   2654      */
   2655 
   2656     public com.ibm.icu.math.BigDecimal setScale(int scale, int round) {
   2657         int ourscale;
   2658         com.ibm.icu.math.BigDecimal res;
   2659         int padding = 0;
   2660         int newlen = 0;
   2661         // at present this naughtily only checks the round value if it is
   2662         // needed (used), for speed
   2663         ourscale = this.scale();
   2664         if (ourscale == scale) // already correct scale
   2665             if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form
   2666                 return this;
   2667         res = clone(this); // need copy
   2668         if (ourscale <= scale) { // simply zero-padding/changing form
   2669             // if ourscale is 0 we may have lots of 0s to add
   2670             if (ourscale == 0)
   2671                 padding = res.exp + scale;
   2672             else
   2673                 padding = scale - ourscale;
   2674             res.mant = extend(res.mant, res.mant.length + padding);
   2675             res.exp = -scale; // as requested
   2676         } else {/* ourscale>scale: shortening, probably */
   2677             if (scale < 0)
   2678                 throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
   2679             // [round() will raise exception if invalid round]
   2680             newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK]
   2681             res = res.round(newlen, round); // round to required length
   2682             // This could have shifted left if round (say) 0.9->1[.0]
   2683             // Repair if so by adding a zero and reducing exponent
   2684             if (res.exp != -scale) {
   2685                 res.mant = extend(res.mant, res.mant.length + 1);
   2686                 res.exp = res.exp - 1;
   2687             }
   2688         }
   2689         res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition
   2690         return res;
   2691     }
   2692 
   2693     /**
   2694      * Converts this <code>BigDecimal</code> to a <code>short</code>. If the <code>BigDecimal</code> has a non-zero
   2695      * decimal part or is out of the possible range for a <code>short</code> (16-bit signed integer) result then an
   2696      * <code>ArithmeticException</code> is thrown.
   2697      *
   2698      * @return A <code>short</code> equal in value to <code>this</code>.
   2699      * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>short</code>.
   2700      * @stable ICU 2.0
   2701      */
   2702 
   2703     public short shortValueExact() {
   2704         int num;
   2705         num = this.intValueExact(); // will check decimal part too
   2706         if ((num > 32767) | (num < (-32768)))
   2707             throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
   2708         return (short) num;
   2709     }
   2710 
   2711     /**
   2712      * Returns the sign of this <code>BigDecimal</code>, as an <code>int</code>. This returns the <i>signum</i> function
   2713      * value that represents the sign of this <code>BigDecimal</code>. That is, -1 if the <code>BigDecimal</code> is
   2714      * negative, 0 if it is numerically equal to zero, or 1 if it is positive.
   2715      *
   2716      * @return An <code>int</code> which is -1 if the <code>BigDecimal</code> is negative, 0 if it is numerically equal
   2717      *         to zero, or 1 if it is positive.
   2718      * @stable ICU 2.0
   2719      */
   2720 
   2721     public int signum() {
   2722         return (int) this.ind; // [note this assumes values for ind.]
   2723     }
   2724 
   2725     /**
   2726      * Converts this <code>BigDecimal</code> to a <code>java.math.BigDecimal</code>.
   2727      * <p>
   2728      * This is an exact conversion; the result is the same as if the <code>BigDecimal</code> were formatted as a plain
   2729      * number without any rounding or exponent and then the <code>java.math.BigDecimal(java.lang.String)</code>
   2730      * constructor were used to construct the result.
   2731      * <p>
   2732      * <i>(Note: this method is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class. It
   2733      * would not be present in a <code>java.math</code> version.)</i>
   2734      *
   2735      * @return The <code>java.math.BigDecimal</code> equal in value to this <code>BigDecimal</code>.
   2736      * @stable ICU 2.0
   2737      */
   2738 
   2739     public java.math.BigDecimal toBigDecimal() {
   2740         return new java.math.BigDecimal(this.unscaledValue(), this.scale());
   2741     }
   2742 
   2743     /**
   2744      * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
   2745      * <p>
   2746      * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use
   2747      * {@link #toBigIntegerExact()}.
   2748      *
   2749      * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
   2750      * @stable ICU 2.0
   2751      */
   2752 
   2753     public java.math.BigInteger toBigInteger() {
   2754         com.ibm.icu.math.BigDecimal res = null;
   2755         int newlen = 0;
   2756         byte newmant[] = null;
   2757         {/* select */
   2758             if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN))
   2759                 res = this; // can layout simply
   2760             else if (exp >= 0) {
   2761                 res = clone(this); // safe copy
   2762                 res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
   2763             } else {
   2764                 { // exp<0; scale to be truncated
   2765                     // we could use divideInteger, but we may as well be quicker
   2766                     if (-this.exp >= this.mant.length)
   2767                         res = ZERO; // all blows away
   2768                     else {
   2769                         res = clone(this); // safe copy
   2770                         newlen = res.mant.length + res.exp;
   2771                         newmant = new byte[newlen]; // [shorter]
   2772                         java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0,
   2773                                 newlen);
   2774                         res.mant = newmant;
   2775                         res.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
   2776                         res.exp = 0;
   2777                     }
   2778                 }
   2779             }
   2780         }
   2781         return new BigInteger(new java.lang.String(res.layout()));
   2782     }
   2783 
   2784     /**
   2785      * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
   2786      * <p>
   2787      * An exception is thrown if the decimal part (if any) is non-zero.
   2788      *
   2789      * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
   2790      * @throws ArithmeticException if <code>this</code> has a non-zero decimal part.
   2791      * @stable ICU 2.0
   2792      */
   2793 
   2794     public java.math.BigInteger toBigIntegerExact() {
   2795         /* test any trailing decimal part */
   2796         if (exp < 0) { // possible decimal part
   2797             /* all decimal places must be 0; note exp<0 */
   2798             if ((!(allzero(mant, mant.length + exp))))
   2799                 throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
   2800         }
   2801         return toBigInteger();
   2802     }
   2803 
   2804     /**
   2805      * Returns the <code>BigDecimal</code> as a character array. The result of this method is the same as using the
   2806      * sequence <code>toString().toCharArray()</code>, but avoids creating the intermediate <code>String</code> and
   2807      * <code>char[]</code> objects.
   2808      *
   2809      * @return The <code>char[]</code> array corresponding to this <code>BigDecimal</code>.
   2810      * @stable ICU 2.0
   2811      */
   2812 
   2813     public char[] toCharArray() {
   2814         return layout();
   2815     }
   2816 
   2817     /**
   2818      * Returns the <code>BigDecimal</code> as a <code>String</code>. This returns a <code>String</code> that exactly
   2819      * represents this <code>BigDecimal</code>, as defined in the decimal documentation (see {@link BigDecimal class
   2820      * header}).
   2821      * <p>
   2822      * By definition, using the {@link #BigDecimal(String)} constructor on the result <code>String</code> will create a
   2823      * <code>BigDecimal</code> that is exactly equal to the original <code>BigDecimal</code>.
   2824      *
   2825      * @return The <code>String</code> exactly corresponding to this <code>BigDecimal</code>.
   2826      * @see #format(int, int)
   2827      * @see #format(int, int, int, int, int, int)
   2828      * @see #toCharArray()
   2829      * @stable ICU 2.0
   2830      */
   2831 
   2832     public java.lang.String toString() {
   2833         return new java.lang.String(layout());
   2834     }
   2835 
   2836     /**
   2837      * Returns the number as a <code>BigInteger</code> after removing the scale. That is, the number is expressed as a
   2838      * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is
   2839      * then converted to a <code>BigInteger</code>.
   2840      *
   2841      * @return The <code>java.math.BigInteger</code> equal in value to this <code>BigDecimal</code> multiplied by ten to
   2842      *         the power of <code>this.scale()</code>.
   2843      * @stable ICU 2.0
   2844      */
   2845 
   2846     public java.math.BigInteger unscaledValue() {
   2847         com.ibm.icu.math.BigDecimal res = null;
   2848         if (exp >= 0)
   2849             res = this;
   2850         else {
   2851             res = clone(this); // safe copy
   2852             res.exp = 0; // drop scale
   2853         }
   2854         return res.toBigInteger();
   2855     }
   2856 
   2857     /**
   2858      * Translates a <code>double</code> to a <code>BigDecimal</code>.
   2859      * <p>
   2860      * Returns a <code>BigDecimal</code> which is the decimal representation of the 64-bit signed binary floating point
   2861      * parameter. If the parameter is infinite, or is not a number (NaN), a <code>NumberFormatException</code> is
   2862      * thrown.
   2863      * <p>
   2864      * The number is constructed as though <code>num</code> had been converted to a <code>String</code> using the <code>
   2865      * Double.toString()</code> method and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
   2866      * This is typically not an exact conversion.
   2867      *
   2868      * @param dub The <code>double</code> to be translated.
   2869      * @return The <code>BigDecimal</code> equal in value to <code>dub</code>.
   2870      * @throws NumberFormatException if the parameter is infinite or not a number.
   2871      * @stable ICU 2.0
   2872      */
   2873 
   2874     public static com.ibm.icu.math.BigDecimal valueOf(double dub) {
   2875         // Reminder: a zero double returns '0.0', so we cannot fastpath to
   2876         // use the constant ZERO. This might be important enough to justify
   2877         // a factory approach, a cache, or a few private constants, later.
   2878         return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());
   2879     }
   2880 
   2881     /**
   2882      * Translates a <code>long</code> to a <code>BigDecimal</code>. That is, returns a plain <code>BigDecimal</code>
   2883      * whose value is equal to the given <code>long</code>.
   2884      *
   2885      * @param lint The <code>long</code> to be translated.
   2886      * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
   2887      * @stable ICU 2.0
   2888      */
   2889 
   2890     public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
   2891         return valueOf(lint, 0);
   2892     }
   2893 
   2894     /**
   2895      * Translates a <code>long</code> to a <code>BigDecimal</code> with a given scale. That is, returns a plain <code>
   2896      * BigDecimal</code> whose unscaled value is equal to the given <code>long</code>, adjusted by the second parameter,
   2897      * <code>scale</code>.
   2898      * <p>
   2899      * The result is given by:
   2900      * <p>
   2901      * <code> (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) </code>
   2902      * <p>
   2903      * A <code>NumberFormatException</code> is thrown if <code>scale</code> is negative.
   2904      *
   2905      * @param lint The <code>long</code> to be translated.
   2906      * @param scale The <code>int</code> scale to be applied.
   2907      * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
   2908      * @throws NumberFormatException if the scale is negative.
   2909      * @stable ICU 2.0
   2910      */
   2911 
   2912     public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) {
   2913         com.ibm.icu.math.BigDecimal res = null;
   2914         {/* select */
   2915             if (lint == 0)
   2916                 res = ZERO;
   2917             else if (lint == 1)
   2918                 res = ONE;
   2919             else if (lint == 10)
   2920                 res = TEN;
   2921             else {
   2922                 res = new com.ibm.icu.math.BigDecimal(lint);
   2923             }
   2924         }
   2925         if (scale == 0)
   2926             return res;
   2927         if (scale < 0)
   2928             throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
   2929         res = clone(res); // safe copy [do not mutate]
   2930         res.exp = -scale; // exponent is -scale
   2931         return res;
   2932     }
   2933 
   2934     /* ---------------------------------------------------------------- */
   2935     /* Private methods */
   2936     /* ---------------------------------------------------------------- */
   2937 
   2938     /*
   2939      * <sgml> Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array).
   2940      * <p>The mantissa will either already have been rounded (following an operation) or will be of length appropriate
   2941      * (in the case of construction from an int, for example). <p>We must not alter the mantissa, here. <p>'form'
   2942      * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure
   2943      * numeric. </sgml>
   2944      */
   2945 
   2946     private char[] layout() {
   2947         char cmant[];
   2948         int i = 0;
   2949         StringBuilder sb = null;
   2950         int euse = 0;
   2951         int sig = 0;
   2952         char csign = 0;
   2953         char rec[] = null;
   2954         int needsign;
   2955         int mag;
   2956         int len = 0;
   2957         cmant = new char[mant.length]; // copy byte[] to a char[]
   2958         {
   2959             int $18 = mant.length;
   2960             i = 0;
   2961             for (; $18 > 0; $18--, i++) {
   2962                 cmant[i] = (char) (mant[i] + ((int) ('0')));
   2963             }
   2964         }/* i */
   2965 
   2966         if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */
   2967             sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999
   2968             if (ind == isneg)
   2969                 sb.append('-');
   2970             euse = (exp + cmant.length) - 1; // exponent to use
   2971             /* setup sig=significant digits and copy to result */
   2972             if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default]
   2973                 sb.append(cmant[0]); // significant character
   2974                 if (cmant.length > 1) // have decimal part
   2975                     sb.append('.').append(cmant, 1, cmant.length - 1);
   2976             } else {
   2977                 do {
   2978                     sig = euse % 3; // common
   2979                     if (sig < 0)
   2980                         sig = 3 + sig; // negative exponent
   2981                     euse = euse - sig;
   2982                     sig++;
   2983                     if (sig >= cmant.length) { // zero padding may be needed
   2984                         sb.append(cmant, 0, cmant.length);
   2985                         {
   2986                             int $19 = sig - cmant.length;
   2987                             for (; $19 > 0; $19--) {
   2988                                 sb.append('0');
   2989                             }
   2990                         }
   2991                     } else { // decimal point needed
   2992                         sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig);
   2993                     }
   2994                 } while (false);
   2995             }/* engineering */
   2996             if (euse != 0) {
   2997                 if (euse < 0) {
   2998                     csign = '-';
   2999                     euse = -euse;
   3000                 } else
   3001                     csign = '+';
   3002                 sb.append('E').append(csign).append(euse);
   3003             }
   3004             rec = new char[sb.length()];
   3005             int srcEnd = sb.length();
   3006             if (0 != srcEnd) {
   3007                 sb.getChars(0, srcEnd, rec, 0);
   3008             }
   3009             return rec;
   3010         }
   3011 
   3012         /* Here for non-exponential (plain) notation */
   3013         if (exp == 0) {/* easy */
   3014             if (ind >= 0)
   3015                 return cmant; // non-negative integer
   3016             rec = new char[cmant.length + 1];
   3017             rec[0] = '-';
   3018             java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, 1, cmant.length);
   3019             return rec;
   3020         }
   3021 
   3022         /* Need a '.' and/or some zeros */
   3023         needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1
   3024 
   3025         /*
   3026          * MAG is the position of the point in the mantissa (index of the character it follows)
   3027          */
   3028         mag = exp + cmant.length;
   3029 
   3030         if (mag < 1) {/* 0.00xxxx form */
   3031             len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length
   3032             rec = new char[len];
   3033             if (needsign != 0)
   3034                 rec[0] = '-';
   3035             rec[needsign] = '0';
   3036             rec[needsign + 1] = '.';
   3037             {
   3038                 int $20 = -mag;
   3039                 i = needsign + 2;
   3040                 for (; $20 > 0; $20--, i++) { // maybe none
   3041                     rec[i] = '0';
   3042                 }
   3043             }/* i */
   3044             java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, (needsign + 2) - mag,
   3045                     cmant.length);
   3046             return rec;
   3047         }
   3048 
   3049         if (mag > cmant.length) {/* xxxx0000 form */
   3050             len = needsign + mag;
   3051             rec = new char[len];
   3052             if (needsign != 0)
   3053                 rec[0] = '-';
   3054             java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, cmant.length);
   3055             {
   3056                 int $21 = mag - cmant.length;
   3057                 i = needsign + cmant.length;
   3058                 for (; $21 > 0; $21--, i++) { // never 0
   3059                     rec[i] = '0';
   3060                 }
   3061             }/* i */
   3062             return rec;
   3063         }
   3064 
   3065         /* decimal point is in the middle of the mantissa */
   3066         len = (needsign + 1) + cmant.length;
   3067         rec = new char[len];
   3068         if (needsign != 0)
   3069             rec[0] = '-';
   3070         java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, mag);
   3071         rec[needsign + mag] = '.';
   3072         java.lang.System.arraycopy((java.lang.Object) cmant, mag, (java.lang.Object) rec, (needsign + mag) + 1,
   3073                 cmant.length - mag);
   3074         return rec;
   3075     }
   3076 
   3077     /*
   3078      * <sgml> Checks a BigDecimal argument to ensure it's a true integer in a given range. <p>If OK, returns it as an
   3079      * int. </sgml>
   3080      */
   3081     // [currently only used by pow]
   3082     private int intcheck(int min, int max) {
   3083         int i;
   3084         i = this.intValueExact(); // [checks for non-0 decimal part]
   3085         // Use same message as though intValueExact failed due to size
   3086         if ((i < min) | (i > max))
   3087             throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i);
   3088         return i;
   3089     }
   3090 
   3091     /* <sgml> Carry out division operations. </sgml> */
   3092     /*
   3093      * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is
   3094      * explicit scale iff code='D' or 'I' (-1 if none).
   3095      *
   3096      * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity):
   3097      *
   3098      * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1)
   3099      * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for
   3100      * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave
   3101      * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -)
   3102      * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If
   3103      * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor
   3104      * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do
   3105      * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if
   3106      * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1
   3107      *
   3108      * For extended commentary, see DMSRCN.
   3109      */
   3110 
   3111     private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs,
   3112             com.ibm.icu.math.MathContext set, int scale) {
   3113         com.ibm.icu.math.BigDecimal lhs;
   3114         int reqdig;
   3115         int newexp;
   3116         com.ibm.icu.math.BigDecimal res;
   3117         int newlen;
   3118         byte var1[];
   3119         int var1len;
   3120         byte var2[];
   3121         int var2len;
   3122         int b2b;
   3123         int have;
   3124         int thisdigit = 0;
   3125         int i = 0;
   3126         byte v2 = 0;
   3127         int ba = 0;
   3128         int mult = 0;
   3129         int start = 0;
   3130         int padding = 0;
   3131         int d = 0;
   3132         byte newvar1[] = null;
   3133         byte lasthave = 0;
   3134         int actdig = 0;
   3135         byte newmant[] = null;
   3136 
   3137         if (set.lostDigits)
   3138             checkdigits(rhs, set.digits);
   3139         lhs = this; // name for clarity
   3140 
   3141         // [note we must have checked lostDigits before the following checks]
   3142         if (rhs.ind == 0)
   3143             throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
   3144         if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s]
   3145             if (set.form != com.ibm.icu.math.MathContext.PLAIN)
   3146                 return ZERO;
   3147             if (scale == (-1))
   3148                 return lhs;
   3149             return lhs.setScale(scale);
   3150         }
   3151 
   3152         /* Prepare numbers according to BigDecimal rules */
   3153         reqdig = set.digits; // local copy (heavily used)
   3154         if (reqdig > 0) {
   3155             if (lhs.mant.length > reqdig)
   3156                 lhs = clone(lhs).round(set);
   3157             if (rhs.mant.length > reqdig)
   3158                 rhs = clone(rhs).round(set);
   3159         } else {/* scaled divide */
   3160             if (scale == (-1))
   3161                 scale = lhs.scale();
   3162             // set reqdig to be at least large enough for the computation
   3163             reqdig = lhs.mant.length; // base length
   3164             // next line handles both positive lhs.exp and also scale mismatch
   3165             if (scale != -lhs.exp)
   3166                 reqdig = (reqdig + scale) + lhs.exp;
   3167             reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect
   3168             if (reqdig < lhs.mant.length)
   3169                 reqdig = lhs.mant.length; // clamp
   3170             if (reqdig < rhs.mant.length)
   3171                 reqdig = rhs.mant.length; // ..
   3172         }
   3173 
   3174         /* precalculate exponent */
   3175         newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length;
   3176         /* If new exponent -ve, then some quick exits are possible */
   3177         if (newexp < 0)
   3178             if (code != 'D') {
   3179                 if (code == 'I')
   3180                     return ZERO; // easy - no integer part
   3181                 /* Must be 'R'; remainder is [finished clone of] input value */
   3182                 return clone(lhs).finish(set, false);
   3183             }
   3184 
   3185         /* We need slow division */
   3186         res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
   3187         res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I)
   3188         res.exp = newexp; // initial exponent (for D/I)
   3189         res.mant = new byte[reqdig + 1]; // where build the result
   3190 
   3191         /* Now [virtually pad the mantissae with trailing zeros */
   3192         // Also copy the LHS, which will be our working array
   3193         newlen = (reqdig + reqdig) + 1;
   3194         var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array
   3195         var1len = newlen; // [remaining digits are 0]
   3196 
   3197         var2 = rhs.mant;
   3198         var2len = newlen;
   3199 
   3200         /* Calculate first two digits of rhs (var2), +1 for later estimations */
   3201         b2b = (var2[0] * 10) + 1;
   3202         if (var2.length > 1)
   3203             b2b = b2b + var2[1];
   3204 
   3205         /* start the long-division loops */
   3206         have = 0;
   3207         {
   3208             outer: for (;;) {
   3209                 thisdigit = 0;
   3210                 /* find the next digit */
   3211                 {
   3212                     inner: for (;;) {
   3213                         if (var1len < var2len)
   3214                             break inner; // V1 too low
   3215                         if (var1len == var2len) { // compare needed
   3216                             {
   3217                                 compare: do { // comparison
   3218                                     {
   3219                                         int $22 = var1len;
   3220                                         i = 0;
   3221                                         for (; $22 > 0; $22--, i++) {
   3222                                             // var1len is always <= var1.length
   3223                                             if (i < var2.length)
   3224                                                 v2 = var2[i];
   3225                                             else
   3226                                                 v2 = (byte) 0;
   3227                                             if (var1[i] < v2)
   3228                                                 break inner; // V1 too low
   3229                                             if (var1[i] > v2)
   3230                                                 break compare; // OK to subtract
   3231                                         }
   3232                                     }/* i */
   3233                                     /*
   3234                                      * reach here if lhs and rhs are identical; subtraction will increase digit by one,
   3235                                      * and the residue will be 0 so we are done; leave the loop with residue set to 0
   3236                                      * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked)
   3237                                      */
   3238                                     thisdigit++;
   3239                                     res.mant[have] = (byte) thisdigit;
   3240                                     have++;
   3241                                     var1[0] = (byte) 0; // residue to 0 [this is all we'll test]
   3242                                     // var1len=1 -- [optimized out]
   3243                                     break outer;
   3244                                 } while (false);
   3245                             }/* compare */
   3246                             /* prepare for subtraction. Estimate BA (lengths the same) */
   3247                             ba = (int) var1[0]; // use only first digit
   3248                         } // lengths the same
   3249                         else {/* lhs longer than rhs */
   3250                             /* use first two digits for estimate */
   3251                             ba = var1[0] * 10;
   3252                             if (var1len > 1)
   3253                                 ba = ba + var1[1];
   3254                         }
   3255                         /* subtraction needed; V1>=V2 */
   3256                         mult = (ba * 10) / b2b;
   3257                         if (mult == 0)
   3258                             mult = 1;
   3259                         thisdigit = thisdigit + mult;
   3260                         // subtract; var1 reusable
   3261                         var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true);
   3262                         if (var1[0] != 0)
   3263                             continue inner; // maybe another subtract needed
   3264                         /*
   3265                          * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than
   3266                          * V2)
   3267                          */
   3268                         {
   3269                             int $23 = var1len - 2;
   3270                             start = 0;
   3271                             start: for (; start <= $23; start++) {
   3272                                 if (var1[start] != 0)
   3273                                     break start;
   3274                                 var1len--;
   3275                             }
   3276                         }/* start */
   3277                         if (start == 0)
   3278                             continue inner;
   3279                         // shift left
   3280                         java.lang.System.arraycopy((java.lang.Object) var1, start, (java.lang.Object) var1, 0, var1len);
   3281                     }
   3282                 }/* inner */
   3283 
   3284                 /* We have the next digit */
   3285                 if ((have != 0) | (thisdigit != 0)) { // put the digit we got
   3286                     res.mant[have] = (byte) thisdigit;
   3287                     have++;
   3288                     if (have == (reqdig + 1))
   3289                         break outer; // we have all we need
   3290                     if (var1[0] == 0)
   3291                         break outer; // residue now 0
   3292                 }
   3293                 /* can leave now if a scaled divide and exponent is small enough */
   3294                 if (scale >= 0)
   3295                     if (-res.exp > scale)
   3296                         break outer;
   3297                 /* can leave now if not Divide and no integer part left */
   3298                 if (code != 'D')
   3299                     if (res.exp <= 0)
   3300                         break outer;
   3301                 res.exp = res.exp - 1; // reduce the exponent
   3302                 /*
   3303                  * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit
   3304                  */
   3305                 var2len--;
   3306             }
   3307         }/* outer */
   3308 
   3309         /* here when we have finished dividing, for some reason */
   3310         // have is the number of digits we collected in res.mant
   3311         if (have == 0)
   3312             have = 1; // res.mant[0] is 0; we always want a digit
   3313 
   3314         if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */
   3315             if ((have + res.exp) > reqdig)
   3316                 throw new java.lang.ArithmeticException("Integer overflow");
   3317 
   3318             if (code == 'R') {
   3319                 do {
   3320                     /* We were doing Remainder -- return the residue */
   3321                     if (res.mant[0] == 0) // no integer part was found
   3322                         return clone(lhs).finish(set, false); // .. so return lhs, canonical
   3323                     if (var1[0] == 0)
   3324                         return ZERO; // simple 0 residue
   3325                     res.ind = lhs.ind; // sign is always as LHS
   3326                     /*
   3327                      * Calculate the exponent by subtracting the number of padding zeros we added and adding the
   3328                      * original exponent
   3329                      */
   3330                     padding = ((reqdig + reqdig) + 1) - lhs.mant.length;
   3331                     res.exp = (res.exp - padding) + lhs.exp;
   3332 
   3333                     /*
   3334                      * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be
   3335                      */
   3336                     d = var1len;
   3337                     {
   3338                         i = d - 1;
   3339                         i: for (; i >= 1; i--) {
   3340                             if (!((res.exp < lhs.exp) & (res.exp < rhs.exp)))
   3341                                 break;
   3342                             if (var1[i] != 0)
   3343                                 break i;
   3344                             d--;
   3345                             res.exp = res.exp + 1;
   3346                         }
   3347                     }/* i */
   3348                     if (d < var1.length) {/* need to reduce */
   3349                         newvar1 = new byte[d];
   3350                         java.lang.System.arraycopy((java.lang.Object) var1, 0, (java.lang.Object) newvar1, 0, d); // shorten
   3351                         var1 = newvar1;
   3352                     }
   3353                     res.mant = var1;
   3354                     return res.finish(set, false);
   3355                 } while (false);
   3356             }/* remainder */
   3357         }
   3358 
   3359         else {/* 'D' -- no overflow check needed */
   3360             // If there was a residue then bump the final digit (iff 0 or 5)
   3361             // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
   3362             // ROUND_UNNECESSARY checks (etc.) later.
   3363             // [if we finished early, the residue will be 0]
   3364             if (var1[0] != 0) { // residue not 0
   3365                 lasthave = res.mant[have - 1];
   3366                 if (((lasthave % 5)) == 0)
   3367                     res.mant[have - 1] = (byte) (lasthave + 1);
   3368             }
   3369         }
   3370 
   3371         /* Here for Divide or Integer Divide */
   3372         // handle scaled results first ['I' always scale 0, optional for 'D']
   3373         if (scale >= 0) {
   3374             do {
   3375                 // say 'scale have res.exp len' scale have res.exp res.mant.length
   3376                 if (have != res.mant.length)
   3377                     // already padded with 0's, so just adjust exponent
   3378                     res.exp = res.exp - ((res.mant.length - have));
   3379                 // calculate number of digits we really want [may be 0]
   3380                 actdig = res.mant.length - (-res.exp - scale);
   3381                 res.round(actdig, set.roundingMode); // round to desired length
   3382                 // This could have shifted left if round (say) 0.9->1[.0]
   3383                 // Repair if so by adding a zero and reducing exponent
   3384                 if (res.exp != -scale) {
   3385                     res.mant = extend(res.mant, res.mant.length + 1);
   3386                     res.exp = res.exp - 1;
   3387                 }
   3388                 return res.finish(set, true); // [strip if not PLAIN]
   3389             } while (false);
   3390         }/* scaled */
   3391 
   3392         // reach here only if a non-scaled
   3393         if (have == res.mant.length) { // got digits+1 digits
   3394             res.round(set);
   3395             have = reqdig;
   3396         } else {/* have<=reqdig */
   3397             if (res.mant[0] == 0)
   3398                 return ZERO; // fastpath
   3399             // make the mantissa truly just 'have' long
   3400             // [we could let finish do this, during strip, if we adjusted
   3401             // the exponent; however, truncation avoids the strip loop]
   3402             newmant = new byte[have]; // shorten
   3403             java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, have);
   3404             res.mant = newmant;
   3405         }
   3406         return res.finish(set, true);
   3407     }
   3408 
   3409     /* <sgml> Report a conversion exception. </sgml> */
   3410 
   3411     private void bad(char s[]) {
   3412         throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s));
   3413     }
   3414 
   3415     /*
   3416      * <sgml> Report a bad argument to a method. </sgml> Arg1 is method name Arg2 is argument position Arg3 is what was
   3417      * found
   3418      */
   3419 
   3420     private void badarg(java.lang.String name, int pos, java.lang.String value) {
   3421         throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " "
   3422                 + value);
   3423     }
   3424 
   3425     /*
   3426      * <sgml> Extend byte array to given length, padding with 0s. If no extension is required then return the same
   3427      * array. </sgml>
   3428      *
   3429      * Arg1 is the source byte array Arg2 is the new length (longer)
   3430      */
   3431 
   3432     private static final byte[] extend(byte inarr[], int newlen) {
   3433         byte newarr[];
   3434         if (inarr.length == newlen)
   3435             return inarr;
   3436         newarr = new byte[newlen];
   3437         java.lang.System.arraycopy((java.lang.Object) inarr, 0, (java.lang.Object) newarr, 0, inarr.length);
   3438         // 0 padding is carried out by the JVM on allocation initialization
   3439         return newarr;
   3440     }
   3441 
   3442     /*
   3443      * <sgml> Add or subtract two >=0 integers in byte arrays <p>This routine performs the calculation: <pre> C=A+(BM)
   3444      * </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
   3445      * non-negative.
   3446      *
   3447      * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B,
   3448      * or 1 longer than that (if a carry occurred).
   3449      *
   3450      * A is not altered unless Arg6 is 1. B is never altered.
   3451      *
   3452      * 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
   3453      * 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)
   3454      *
   3455      * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance
   3456      * degradation.
   3457      */
   3458     // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
   3459     // 1997.10.05 -- changed to byte arrays (from char arrays)
   3460     // 1998.07.01 -- changed to allow destructive reuse of LHS
   3461     // 1998.07.01 -- changed to allow virtual lengths for the arrays
   3462     // 1998.12.29 -- use lookaside for digit/carry calculation
   3463     // 1999.08.07 -- avoid multiply when mult=1, and make db an int
   3464     // 1999.12.22 -- special case m=-1, also drop 0 special case
   3465     private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) {
   3466         int alength;
   3467         int blength;
   3468         int ap;
   3469         int bp;
   3470         int maxarr;
   3471         byte reb[];
   3472         boolean quickm;
   3473         int digit;
   3474         int op = 0;
   3475         int dp90 = 0;
   3476         byte newarr[];
   3477         int i = 0;
   3478 
   3479         // We'll usually be right if we assume no carry
   3480         alength = a.length; // physical lengths
   3481         blength = b.length; // ..
   3482         ap = avlen - 1; // -> final (rightmost) digit
   3483         bp = bvlen - 1; // ..
   3484         maxarr = bp;
   3485         if (maxarr < ap)
   3486             maxarr = ap;
   3487         reb = (byte[]) null; // result byte array
   3488         if (reuse)
   3489             if ((maxarr + 1) == alength)
   3490                 reb = a; // OK to reuse A
   3491         if (reb == null)
   3492             reb = new byte[maxarr + 1]; // need new array
   3493 
   3494         quickm = false; // 1 if no multiply needed
   3495         if (m == 1)
   3496             quickm = true; // most common
   3497         else if (m == (-1))
   3498             quickm = true; // also common
   3499 
   3500         digit = 0; // digit, with carry or borrow
   3501         {
   3502             op = maxarr;
   3503             op: for (; op >= 0; op--) {
   3504                 if (ap >= 0) {
   3505                     if (ap < alength)
   3506                         digit = digit + a[ap]; // within A
   3507                     ap--;
   3508                 }
   3509                 if (bp >= 0) {
   3510                     if (bp < blength) { // within B
   3511                         if (quickm) {
   3512                             if (m > 0)
   3513                                 digit = digit + b[bp]; // most common
   3514                             else
   3515                                 digit = digit - b[bp]; // also common
   3516                         } else
   3517                             digit = digit + (b[bp] * m);
   3518                     }
   3519                     bp--;
   3520                 }
   3521                 /* result so far (digit) could be -90 through 99 */
   3522                 if (digit < 10)
   3523                     if (digit >= 0) {
   3524                         do { // 0-9
   3525                             reb[op] = (byte) digit;
   3526                             digit = 0; // no carry
   3527                             continue op;
   3528                         } while (false);
   3529                     }/* quick */
   3530                 dp90 = digit + 90;
   3531                 reb[op] = bytedig[dp90]; // this digit
   3532                 digit = bytecar[dp90]; // carry or borrow
   3533             }
   3534         }/* op */
   3535 
   3536         if (digit == 0)
   3537             return reb; // no carry
   3538         // following line will become an Assert, later
   3539         // if digit<0 then signal ArithmeticException("internal.error ["digit"]")
   3540 
   3541         /* We have carry -- need to make space for the extra digit */
   3542         newarr = (byte[]) null;
   3543         if (reuse)
   3544             if ((maxarr + 2) == a.length)
   3545                 newarr = a; // OK to reuse A
   3546         if (newarr == null)
   3547             newarr = new byte[maxarr + 2];
   3548         newarr[0] = (byte) digit; // the carried digit ..
   3549         // .. and all the rest [use local loop for short numbers]
   3550         if (maxarr < 10) {
   3551             int $24 = maxarr + 1;
   3552             i = 0;
   3553             for (; $24 > 0; $24--, i++) {
   3554                 newarr[i + 1] = reb[i];
   3555             }
   3556         }/* i */
   3557         else
   3558             java.lang.System.arraycopy((java.lang.Object) reb, 0, (java.lang.Object) newarr, 1, maxarr + 1);
   3559         return newarr;
   3560     }
   3561 
   3562     /*
   3563      * <sgml> Initializer for digit array properties (lookaside). </sgml> Returns the digit array, and initializes the
   3564      * carry array.
   3565      */
   3566 
   3567     private static final byte[] diginit() {
   3568         byte work[];
   3569         int op = 0;
   3570         int digit = 0;
   3571         work = new byte[(90 + 99) + 1];
   3572         {
   3573             op = 0;
   3574             op: for (; op <= (90 + 99); op++) {
   3575                 digit = op - 90;
   3576                 if (digit >= 0) {
   3577                     work[op] = (byte) (digit % 10);
   3578                     bytecar[op] = (byte) (digit / 10); // calculate carry
   3579                     continue op;
   3580                 }
   3581                 // borrowing...
   3582                 digit = digit + 100; // yes, this is right [consider -50]
   3583                 work[op] = (byte) (digit % 10);
   3584                 bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %]
   3585             }
   3586         }/* op */
   3587         return work;
   3588     }
   3589 
   3590     /*
   3591      * <sgml> Create a copy of BigDecimal object for local use. <p>This does NOT make a copy of the mantissa array.
   3592      * </sgml> Arg1 is the BigDecimal to clone (non-null)
   3593      */
   3594 
   3595     private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) {
   3596         com.ibm.icu.math.BigDecimal copy;
   3597         copy = new com.ibm.icu.math.BigDecimal();
   3598         copy.ind = dec.ind;
   3599         copy.exp = dec.exp;
   3600         copy.form = dec.form;
   3601         copy.mant = dec.mant;
   3602         return copy;
   3603     }
   3604 
   3605     /*
   3606      * <sgml> Check one or two numbers for lost digits. </sgml> Arg1 is RHS (or null, if none) Arg2 is current DIGITS
   3607      * setting returns quietly or throws an exception
   3608      */
   3609 
   3610     private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) {
   3611         if (dig == 0)
   3612             return; // don't check if digits=0
   3613         // first check lhs...
   3614         if (this.mant.length > dig)
   3615             if ((!(allzero(this.mant, dig))))
   3616                 throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString());
   3617         if (rhs == null)
   3618             return; // monadic
   3619         if (rhs.mant.length > dig)
   3620             if ((!(allzero(rhs.mant, dig))))
   3621                 throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
   3622     }
   3623 
   3624     /*
   3625      * <sgml> Round to specified digits, if necessary. </sgml> Arg1 is requested MathContext [with length and rounding
   3626      * mode] returns this, for convenience
   3627      */
   3628 
   3629     private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) {
   3630         return round(set.digits, set.roundingMode);
   3631     }
   3632 
   3633     /*
   3634      * <sgml> Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when
   3635      * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience
   3636      *
   3637      * ind and exp are adjusted, but not cleared for a mantissa of zero
   3638      *
   3639      * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa
   3640      * length will be 1. </sgml>
   3641      */
   3642 
   3643     private com.ibm.icu.math.BigDecimal round(int len, int mode) {
   3644         int adjust;
   3645         int sign;
   3646         byte oldmant[];
   3647         boolean reuse = false;
   3648         byte first = 0;
   3649         int increment;
   3650         byte newmant[] = null;
   3651         adjust = mant.length - len;
   3652         if (adjust <= 0)
   3653             return this; // nowt to do
   3654 
   3655         exp = exp + adjust; // exponent of result
   3656         sign = (int) ind; // save [assumes -1, 0, 1]
   3657         oldmant = mant; // save
   3658         if (len > 0) {
   3659             // remove the unwanted digits
   3660             mant = new byte[len];
   3661             java.lang.System.arraycopy((java.lang.Object) oldmant, 0, (java.lang.Object) mant, 0, len);
   3662             reuse = true; // can reuse mantissa
   3663             first = oldmant[len]; // first of discarded digits
   3664         } else {/* len<=0 */
   3665             mant = ZERO.mant;
   3666             ind = iszero;
   3667             reuse = false; // cannot reuse mantissa
   3668             if (len == 0)
   3669                 first = oldmant[0];
   3670             else
   3671                 first = (byte) 0; // [virtual digit]
   3672         }
   3673 
   3674         // decide rounding adjustment depending on mode, sign, and discarded digits
   3675         increment = 0; // bumper
   3676         {
   3677             do {/* select */
   3678                 if (mode == ROUND_HALF_UP) { // default first [most common]
   3679                     if (first >= 5)
   3680                         increment = sign;
   3681                 } else if (mode == ROUND_UNNECESSARY) { // default for setScale()
   3682                     // discarding any non-zero digits is an error
   3683                     if ((!(allzero(oldmant, len))))
   3684                         throw new java.lang.ArithmeticException("Rounding necessary");
   3685                 } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down
   3686                     if (first > 5)
   3687                         increment = sign;
   3688                     else if (first == 5)
   3689                         if ((!(allzero(oldmant, len + 1))))
   3690                             increment = sign;
   3691                 } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even
   3692                     if (first > 5)
   3693                         increment = sign;
   3694                     else if (first == 5) {
   3695                         if ((!(allzero(oldmant, len + 1))))
   3696                             increment = sign;
   3697                         else /* 0.5000 */
   3698                         if ((((mant[mant.length - 1]) % 2)) == 1)
   3699                             increment = sign;
   3700                     }
   3701                 } else if (mode == ROUND_DOWN) {
   3702                     // never increment
   3703                 } else if (mode == ROUND_UP) { // increment if discarded non-zero
   3704                     if ((!(allzero(oldmant, len))))
   3705                         increment = sign;
   3706                 } else if (mode == ROUND_CEILING) { // more positive
   3707                     if (sign > 0)
   3708                         if ((!(allzero(oldmant, len))))
   3709                             increment = sign;
   3710                 } else if (mode == ROUND_FLOOR) { // more negative
   3711                     if (sign < 0)
   3712                         if ((!(allzero(oldmant, len))))
   3713                             increment = sign;
   3714                 } else {
   3715                     throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode);
   3716                 }
   3717             } while (false);
   3718         }/* modes */
   3719 
   3720         if (increment != 0) {
   3721             do {
   3722                 if (ind == iszero) {
   3723                     // we must not subtract from 0, but result is trivial anyway
   3724                     mant = ONE.mant;
   3725                     ind = (byte) increment;
   3726                 } else {
   3727                     // mantissa is non-0; we can safely add or subtract 1
   3728                     if (ind == isneg)
   3729                         increment = -increment;
   3730                     newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse);
   3731                     if (newmant.length > mant.length) { // had a carry
   3732                         // drop rightmost digit and raise exponent
   3733                         exp++;
   3734                         // mant is already the correct length
   3735                         java.lang.System.arraycopy((java.lang.Object) newmant, 0, (java.lang.Object) mant, 0,
   3736                                 mant.length);
   3737                     } else
   3738                         mant = newmant;
   3739                 }
   3740             } while (false);
   3741         }/* bump */
   3742         // rounding can increase exponent significantly
   3743         if (exp > MaxExp)
   3744             throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
   3745         return this;
   3746     }
   3747 
   3748     /*
   3749      * <sgml> Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to
   3750      * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0
   3751      *
   3752      * Arg2 may be beyond array bounds, in which case 1 is returned </sgml>
   3753      */
   3754 
   3755     private static final boolean allzero(byte array[], int start) {
   3756         int i = 0;
   3757         if (start < 0)
   3758             start = 0;
   3759         {
   3760             int $25 = array.length - 1;
   3761             i = start;
   3762             for (; i <= $25; i++) {
   3763                 if (array[i] != 0)
   3764                     return false;
   3765             }
   3766         }/* i */
   3767         return true;
   3768     }
   3769 
   3770     /*
   3771      * <sgml> Carry out final checks and canonicalization <p> This finishes off the current number by: 1. Rounding if
   3772      * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping
   3773      * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0'
   3774      * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. </sgml> Arg1 is requested
   3775      * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed
   3776      * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience
   3777      */
   3778 
   3779     private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) {
   3780         int d = 0;
   3781         int i = 0;
   3782         byte newmant[] = null;
   3783         int mag = 0;
   3784         int sig = 0;
   3785         /* Round if mantissa too long and digits requested */
   3786         if (set.digits != 0)
   3787             if (this.mant.length > set.digits)
   3788                 this.round(set);
   3789 
   3790         /*
   3791          * If strip requested (and standard formatting), remove insignificant trailing zeros.
   3792          */
   3793         if (strip)
   3794             if (set.form != com.ibm.icu.math.MathContext.PLAIN) {
   3795                 d = this.mant.length;
   3796                 /* see if we need to drop any trailing zeros */
   3797                 {
   3798                     i = d - 1;
   3799                     i: for (; i >= 1; i--) {
   3800                         if (this.mant[i] != 0)
   3801                             break i;
   3802                         d--;
   3803                         exp++;
   3804                     }
   3805                 }/* i */
   3806                 if (d < this.mant.length) {/* need to reduce */
   3807                     newmant = new byte[d];
   3808                     java.lang.System.arraycopy((java.lang.Object) this.mant, 0, (java.lang.Object) newmant, 0, d);
   3809                     this.mant = newmant;
   3810                 }
   3811             }
   3812 
   3813         form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset
   3814 
   3815         /* Now check for leading- and all- zeros in mantissa */
   3816         {
   3817             int $26 = this.mant.length;
   3818             i = 0;
   3819             for (; $26 > 0; $26--, i++) {
   3820                 if (this.mant[i] != 0) {
   3821                     // non-0 result; ind will be correct
   3822                     // remove leading zeros [e.g., after subtract]
   3823                     if (i > 0) {
   3824                         do {
   3825                             newmant = new byte[this.mant.length - i];
   3826                             java.lang.System.arraycopy((java.lang.Object) this.mant, i, (java.lang.Object) newmant, 0,
   3827                                     this.mant.length - i);
   3828                             this.mant = newmant;
   3829                         } while (false);
   3830                     }/* delead */
   3831                     // now determine form if not PLAIN
   3832                     mag = exp + mant.length;
   3833                     if (mag > 0) { // most common path
   3834                         if (mag > set.digits)
   3835                             if (set.digits != 0)
   3836                                 form = (byte) set.form;
   3837                         if ((mag - 1) <= MaxExp)
   3838                             return this; // no overflow; quick return
   3839                     } else if (mag < (-5))
   3840                         form = (byte) set.form;
   3841                     /* check for overflow */
   3842                     mag--;
   3843                     if ((mag < MinExp) | (mag > MaxExp)) {
   3844                         overflow: do {
   3845                             // possible reprieve if form is engineering
   3846                             if (form == com.ibm.icu.math.MathContext.ENGINEERING) {
   3847                                 sig = mag % 3; // leftover
   3848                                 if (sig < 0)
   3849                                     sig = 3 + sig; // negative exponent
   3850                                 mag = mag - sig; // exponent to use
   3851                                 // 1999.06.29: second test here must be MaxExp
   3852                                 if (mag >= MinExp)
   3853                                     if (mag <= MaxExp)
   3854                                         break overflow;
   3855                             }
   3856                             throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag);
   3857                         } while (false);
   3858                     }/* overflow */
   3859                     return this;
   3860                 }
   3861             }
   3862         }/* i */
   3863 
   3864         // Drop through to here only if mantissa is all zeros
   3865         ind = iszero;
   3866         {/* select */
   3867             if (set.form != com.ibm.icu.math.MathContext.PLAIN)
   3868                 exp = 0; // standard result; go to '0'
   3869             else if (exp > 0)
   3870                 exp = 0; // +ve exponent also goes to '0'
   3871             else {
   3872                 // a plain number with -ve exponent; preserve and check exponent
   3873                 if (exp < MinExp)
   3874                     throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
   3875             }
   3876         }
   3877         mant = ZERO.mant; // canonical mantissa
   3878         return this;
   3879     }
   3880 }
   3881