1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 /* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
5 /* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
6 package android.icu.math;
7 
8 import java.math.BigInteger;
9 
10 import android.icu.lang.UCharacter;
11 
12 /* ------------------------------------------------------------------ */
13 /* BigDecimal -- Decimal arithmetic for Java                          */
14 /* ------------------------------------------------------------------ */
15 /* Copyright IBM Corporation, 1996-2016.  All Rights Reserved.       */
16 /*                                                                    */
17 /* The BigDecimal class provides immutable arbitrary-precision        */
18 /* floating point (including integer) decimal numbers.                */
19 /*                                                                    */
20 /* As the numbers are decimal, there is an exact correspondence       */
21 /* between an instance of a BigDecimal object and its String          */
22 /* representation; the BigDecimal class provides direct conversions   */
23 /* to and from String and character array objects, and well as        */
24 /* conversions to and from the Java primitive types (which may not    */
25 /* be exact).                                                         */
26 /* ------------------------------------------------------------------ */
27 /* Notes:                                                             */
28 /*                                                                    */
29 /* 1. A BigDecimal object is never changed in value once constructed; */
30 /*    this avoids the need for locking.  Note in particular that the  */
31 /*    mantissa array may be shared between many BigDecimal objects,   */
32 /*    so that once exposed it must not be altered.                    */
33 /*                                                                    */
34 /* 2. This class looks at MathContext class fields directly (for      */
35 /*    performance).  It must not and does not change them.            */
36 /*                                                                    */
37 /* 3. Exponent checking is delayed until finish(), as we know         */
38 /*    intermediate calculations cannot cause 31-bit overflow.         */
39 /*    [This assertion depends on MAX_DIGITS in MathContext.]          */
40 /*                                                                    */
41 /* 4. Comments for the public API now follow the javadoc conventions. */
42 /*    The NetRexx -comments option is used to pass these comments     */
43 /*    through to the generated Java code (with -format, if desired).  */
44 /*                                                                    */
45 /* 5. System.arraycopy is faster than explicit loop as follows        */
46 /*      Mean length 4:  equal                                         */
47 /*      Mean length 8:  x2                                            */
48 /*      Mean length 16: x3                                            */
49 /*      Mean length 24: x4                                            */
50 /*    From prior experience, we expect mean length a little below 8,  */
51 /*    but arraycopy is still the one to use, in general, until later  */
52 /*    measurements suggest otherwise.                                 */
53 /*                                                                    */
54 /* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370     */
55 /*    assembler code implementation of the algorithms below; it is    */
56 /*    now called IXXRCN and is available with the OS/390 and VM/ESA   */
57 /*    operating systems.                                              */
58 /* ------------------------------------------------------------------ */
59 /* Change History:                                                    */
60 /* 1997.09.02 Initial version (derived from netrexx.lang classes)     */
61 /* 1997.09.12 Add lostDigits checking                                 */
62 /* 1997.10.06 Change mantissa to a byte array                         */
63 /* 1997.11.22 Rework power [did not prepare arguments, etc.]          */
64 /* 1997.12.13 multiply did not prepare arguments                      */
65 /* 1997.12.14 add did not prepare and align arguments correctly       */
66 /* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle      */
67 /* 1998.05.21 adjust remainder operator finalization                  */
68 /* 1998.06.04 rework to pass MathContext to finish() and round()      */
69 /* 1998.06.06 change format to use round(); support rounding modes    */
70 /* 1998.06.25 rename to BigDecimal and begin merge                    */
71 /*            zero can now have trailing zeros (i.e., exp\=0)         */
72 /* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger         */
73 /*                         unscaledValue, valueof                     */
74 /* 1998.07.01 improve byteaddsub to allow array reuse, etc.           */
75 /* 1998.07.01 make null testing explicit to avoid JIT bug [Win32]     */
76 /* 1998.07.07 scaled division  [divide(BigDecimal, int, int)]         */
77 /* 1998.07.08 setScale, faster equals                                 */
78 /* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
79 /* 1998.10.12 change package to android.icu.math                          */
80 /* 1998.12.14 power operator no longer rounds RHS [to match ANSI]     */
81 /*            add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
82 /* 1998.12.29 improve byteaddsub by using table lookup                */
83 /* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
84 /* 1999.02.05 cleaner code for BigDecimal(char[])                     */
85 /* 1999.02.06 add javadoc comments                                    */
86 /* 1999.02.11 format() changed from 7 to 2 method form                */
87 /* 1999.03.05 null pointer checking is no longer explicit             */
88 /* 1999.03.05 simplify; changes from discussion with J. Bloch:        */
89 /*            null no longer permitted for MathContext; drop boolean, */
90 /*            byte, char, float, short constructor, deprecate double  */
91 /*            constructor, no blanks in string constructor, add       */
92 /*            offset and length version of char[] constructor;        */
93 /*            add valueOf(double); drop booleanValue, charValue;      */
94 /*            add ...Exact versions of remaining convertors           */
95 /* 1999.03.13 add toBigIntegerExact                                   */
96 /* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
97 /* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic          */
98 /* 1999.06.29 1.02 constructors should not allow exponent > 9 digits  */
99 /* 1999.07.03 1.03 lost digits should not be checked if digits=0      */
100 /* 1999.07.06      lost digits Exception message changed              */
101 /* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic)             */
102 /* 1999.07.17      improve messages from pow method                   */
103 /* 1999.08.08      performance tweaks                                 */
104 /* 1999.08.15      fastpath in multiply                               */
105 /* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555]    */
106 /* 1999.12.22 1.06 remove multiply fastpath, and improve performance  */
107 /* 2000.01.01      copyright update [Y2K has arrived]                 */
108 /* 2000.06.18 1.08 no longer deprecate BigDecimal(double)             */
109 /* ------------------------------------------------------------------ */
110 
111 /**
112  * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the
113  * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format
114  * conversions, and hashing.
115  * <p>
116  * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object
117  * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from
118  * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java
119  * primitive types (which may not be exact) and <code>BigInteger</code>.
120  * <p>
121  * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number
122  * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal
123  * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any
124  * operation.
125  * <p>
126  * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also
127  * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br>
128  * <i>[This URL will change.]</i>
129  *
130  * <h3>Operator methods</h3>
131  * <p>
132  * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the
133  * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code>
134  * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as
135  * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9,
136  * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point
137  * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>.
138  * <p>
139  * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this
140  * version of each method, the context settings used are <code>digits=0,
141  * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with
142  * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2.
143  * <p>
144  * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the
145  * current object.
146  * <p>
147  * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The
148  * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being
149  * the right-hand operand.
150  * <p>
151  * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and
152  * <code>extra</code> could be written as any of:
153  * <p>
154  * <code>
155  *     award.add(extra)
156  * <br>award.add(extra, MathContext.DEFAULT)
157  * <br>award.add(extra, acontext)
158  * </code>
159  * <p>
160  * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code>
161  * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context
162  * settings.
163  * <p>
164  * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by
165  * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal
166  * arithmetic documentation (see the URL above), but in summary:
167  * <ul>
168  * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the
169  * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be
170  * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br>
171  * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code>
172  * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled)
173  * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code>
174  * parameter). <br>
175  * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm.
176  * <li>
177  * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is
178  * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part).
179  * <li>
180  * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast
181  * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros
182  * in the fractional part of results). <br>
183  * So, for example:
184  * <p>
185  * <code>
186  *     new BigDecimal("2.40").add(     new BigDecimal("2"))      =&gt; "4.40"
187  * <br>new BigDecimal("2.40").subtract(new BigDecimal("2"))      =&gt; "0.40"
188  * <br>new BigDecimal("2.40").multiply(new BigDecimal("2"))      =&gt; "4.80"
189  * <br>new BigDecimal("2.40").divide(  new BigDecimal("2"), def) =&gt; "1.2"
190  * </code>
191  * <p>
192  * where the value on the right of the <code>=&gt;</code> would be the result of the operation, expressed as a
193  * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code>
194  * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If
195  * necessary, trailing zeros may be easily removed using division by 1.
196  * <li>
197  * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of
198  * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the
199  * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number
200  * will be expressed in exponential notation; thus
201  * <p>
202  * <code>
203  *   new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
204  * </code>
205  * <p>
206  * results in <code>1E+12</code> instead of <code>1000000000000</code>, and
207  * <p>
208  * <code>
209  *   new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
210  * </code>
211  * <p>
212  * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>.
213  * <p>
214  * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting.
215  * </ul>
216  * <p>
217  * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>,
218  * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
219  *
220  * @see MathContext
221  * @author Mike Cowlishaw
222  */
223 
224 public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> {
225     // private static final java.lang.String $0="BigDecimal.nrx";
226 
227     /* ----- Constants ----- */
228     /* properties constant public */// useful to others
229     /**
230      * The <code>BigDecimal</code> constant "0".
231      *
232      * @see #ONE
233      * @see #TEN
234      */
235     public static final android.icu.math.BigDecimal ZERO = new android.icu.math.BigDecimal((long) 0); // use long as we
236                                                                                                       // want the int
237                                                                                                       // constructor
238     // .. to be able to use this, for speed
239 
240     /**
241      * The <code>BigDecimal</code> constant "1".
242      *
243      * @see #TEN
244      * @see #ZERO
245      */
246     public static final android.icu.math.BigDecimal ONE = new android.icu.math.BigDecimal((long) 1); // use long as we
247                                                                                                      // want the int
248                                                                                                      // constructor
249     // .. to be able to use this, for speed
250 
251     /**
252      * The <code>BigDecimal</code> constant "10".
253      *
254      * @see #ONE
255      * @see #ZERO
256      */
257     public static final android.icu.math.BigDecimal TEN = new android.icu.math.BigDecimal(10);
258 
259     // the rounding modes (copied here for upwards compatibility)
260     /**
261      * Rounding mode to round to a more positive number.
262      *
263      * @see MathContext#ROUND_CEILING
264      */
265     public static final int ROUND_CEILING = android.icu.math.MathContext.ROUND_CEILING;
266 
267     /**
268      * Rounding mode to round towards zero.
269      *
270      * @see MathContext#ROUND_DOWN
271      */
272     public static final int ROUND_DOWN = android.icu.math.MathContext.ROUND_DOWN;
273 
274     /**
275      * Rounding mode to round to a more negative number.
276      *
277      * @see MathContext#ROUND_FLOOR
278      */
279     public static final int ROUND_FLOOR = android.icu.math.MathContext.ROUND_FLOOR;
280 
281     /**
282      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down.
283      *
284      * @see MathContext#ROUND_HALF_DOWN
285      */
286     public static final int ROUND_HALF_DOWN = android.icu.math.MathContext.ROUND_HALF_DOWN;
287 
288     /**
289      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor.
290      *
291      * @see MathContext#ROUND_HALF_EVEN
292      */
293     public static final int ROUND_HALF_EVEN = android.icu.math.MathContext.ROUND_HALF_EVEN;
294 
295     /**
296      * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up.
297      *
298      * @see MathContext#ROUND_HALF_UP
299      */
300     public static final int ROUND_HALF_UP = android.icu.math.MathContext.ROUND_HALF_UP;
301 
302     /**
303      * Rounding mode to assert that no rounding is necessary.
304      *
305      * @see MathContext#ROUND_UNNECESSARY
306      */
307     public static final int ROUND_UNNECESSARY = android.icu.math.MathContext.ROUND_UNNECESSARY;
308 
309     /**
310      * Rounding mode to round away from zero.
311      *
312      * @see MathContext#ROUND_UP
313      */
314     public static final int ROUND_UP = android.icu.math.MathContext.ROUND_UP;
315 
316     /* properties constant private */// locals
317     private static final byte ispos = 1; // ind: indicates positive (must be 1)
318     private static final byte iszero = 0; // ind: indicates zero (must be 0)
319     private static final byte isneg = -1; // ind: indicates negative (must be -1)
320     // [later could add NaN, +/- infinity, here]
321 
322     private static final int MinExp = -999999999; // minimum exponent allowed
323     private static final int MaxExp = 999999999; // maximum exponent allowed
324     private static final int MinArg = -999999999; // minimum argument integer
325     private static final int MaxArg = 999999999; // maximum argument integer
326 
327     private static final android.icu.math.MathContext plainMC = new android.icu.math.MathContext(0,
328             android.icu.math.MathContext.PLAIN); // context for plain unlimited math
329 
330     /* properties constant private unused */// present but not referenced
331     // Serialization version
332     private static final long serialVersionUID = 8245355804974198832L;
333 
334     // private static final java.lang.String
335     // copyright=" Copyright (c) IBM Corporation 1996, 2000.  All rights reserved. ";
336 
337     /* properties static private */
338     // Precalculated constant arrays (used by byteaddsub)
339     private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
340     private static byte bytedig[] = diginit(); // next digit array
341 
342     /* ----- Instance properties [all private and immutable] ----- */
343     /* properties private */
344 
345     /**
346      * The indicator. This may take the values:
347      * <ul>
348      * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative
349      * </ul>
350      *
351      * @serial
352      */
353     private byte ind; // assumed undefined
354     // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
355     // We only need two bits for this, but use a byte [also permits
356     // smooth future extension].
357 
358     /**
359      * The formatting style. This may take the values:
360      * <ul>
361      * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li>
362      * MathContext.ENGINEERING -- engineering notation required
363      * </ul>
364      * <p>
365      * This property is an optimization; it allows us to defer number layout until it is actually needed as a string,
366      * hence avoiding unnecessary formatting.
367      *
368      * @serial
369      */
370     private byte form = (byte) android.icu.math.MathContext.PLAIN; // assumed PLAIN
371     // We only need two bits for this, at present, but use a byte
372     // [again, to allow for smooth future extension]
373 
374     /**
375      * The value of the mantissa.
376      * <p>
377      * Once constructed, this may become shared between several BigDecimal objects, so must not be altered.
378      * <p>
379      * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -&gt; 9.
380      * <p>
381      * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a
382      * plain number, for example, 0.000).
383      *
384      * @serial
385      */
386     private byte mant[]; // assumed null
387 
388     /**
389      * The exponent.
390      * <p>
391      * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero.
392      *
393      * Note that this property can have a value less than MinExp when the mantissa has more than one digit.
394      *
395      * @serial
396      */
397     private int exp;
398 
399     // assumed 0
400 
401     /* ---------------------------------------------------------------- */
402     /* Constructors */
403     /* ---------------------------------------------------------------- */
404 
405     /**
406      * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>.
407      * <p>
408      * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using
409      * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
410      * The parameter must not be <code>null</code>.
411      * <p>
412      * <i>(Note: this constructor is provided only in the <code>android.icu.math</code> version of the BigDecimal class.
413      * It would not be present in a <code>java.math</code> version.)</i>
414      *
415      * @param bd The <code>BigDecimal</code> to be translated.
416      */
417 
BigDecimal(java.math.BigDecimal bd)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 
BigDecimal(java.math.BigInteger bi)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 
BigDecimal(java.math.BigInteger bi, int scale)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 
BigDecimal(char inchars[])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 
BigDecimal(char inchars[], int offset, int length)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 
BigDecimal(double num)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 
BigDecimal(int num)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 
BigDecimal(long num)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 
BigDecimal(java.lang.String string)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 
BigDecimal()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 
abs()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 
abs(android.icu.math.MathContext set)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 
add(android.icu.math.BigDecimal rhs)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 
add(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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
compareTo(android.icu.math.BigDecimal rhs)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 
compareTo(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
divide(android.icu.math.BigDecimal rhs)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 
divide(android.icu.math.BigDecimal rhs, int round)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 
divide(android.icu.math.BigDecimal rhs, int scale, int round)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 
divide(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
divideInteger(android.icu.math.BigDecimal rhs)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 
divideInteger(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
max(android.icu.math.BigDecimal rhs)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 
max(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
min(android.icu.math.BigDecimal rhs)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 
min(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
multiply(android.icu.math.BigDecimal rhs)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 
multiply(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
negate()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 
negate(android.icu.math.MathContext set)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 
plus()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 
plus(android.icu.math.MathContext set)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 
pow(android.icu.math.BigDecimal rhs)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 
pow(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
remainder(android.icu.math.BigDecimal rhs)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 
remainder(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
subtract(android.icu.math.BigDecimal rhs)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 
subtract(android.icu.math.BigDecimal rhs, android.icu.math.MathContext set)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 
byteValueExact()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
doubleValue()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
equals(java.lang.Object obj)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
floatValue()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 
format(int before, int after)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 
format(int before, int after, int explaces, int exdigits, int exformint, int exround)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
hashCode()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
intValue()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 
intValueExact()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
longValue()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 
longValueExact()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 
movePointLeft(int n)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 
movePointRight(int n)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 
scale()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 
setScale(int scale)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 
setScale(int scale, int round)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 
shortValueExact()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 
signum()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 
toBigDecimal()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 
toBigInteger()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 
toBigIntegerExact()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 
toCharArray()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
toString()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 
unscaledValue()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 
valueOf(double dub)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 
valueOf(long lint)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 
valueOf(long lint, int scale)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 
layout()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]
intcheck(int min, int max)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 
dodivide(char code, android.icu.math.BigDecimal rhs, android.icu.math.MathContext set, int scale)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 
bad(char s[])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 
badarg(java.lang.String name, int pos, java.lang.String value)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 
extend(byte inarr[], int newlen)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
byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse)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 
diginit()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 
clone(android.icu.math.BigDecimal dec)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 
checkdigits(android.icu.math.BigDecimal rhs, int dig)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 
round(android.icu.math.MathContext set)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 
round(int len, int mode)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 
allzero(byte array[], int start)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 
finish(android.icu.math.MathContext set, boolean strip)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