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