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