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