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