12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.math;
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.math.BigInteger;
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.lang.UCharacter;
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* ------------------------------------------------------------------ */
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* BigDecimal -- Decimal arithmetic for Java                          */
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* ------------------------------------------------------------------ */
14bee65486a185907111f3be60992433e133ec0e32Scott Russell/* Copyright IBM Corporation, 1996-2016.  All Rights Reserved.       */
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* The BigDecimal class provides immutable arbitrary-precision        */
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* floating point (including integer) decimal numbers.                */
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* As the numbers are decimal, there is an exact correspondence       */
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* between an instance of a BigDecimal object and its String          */
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* representation; the BigDecimal class provides direct conversions   */
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* to and from String and character array objects, and well as        */
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* conversions to and from the Java primitive types (which may not    */
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* be exact).                                                         */
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* ------------------------------------------------------------------ */
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* Notes:                                                             */
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1. A BigDecimal object is never changed in value once constructed; */
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    this avoids the need for locking.  Note in particular that the  */
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    mantissa array may be shared between many BigDecimal objects,   */
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    so that once exposed it must not be altered.                    */
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 2. This class looks at MathContext class fields directly (for      */
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    performance).  It must not and does not change them.            */
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 3. Exponent checking is delayed until finish(), as we know         */
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    intermediate calculations cannot cause 31-bit overflow.         */
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    [This assertion depends on MAX_DIGITS in MathContext.]          */
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 4. Comments for the public API now follow the javadoc conventions. */
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    The NetRexx -comments option is used to pass these comments     */
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    through to the generated Java code (with -format, if desired).  */
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 5. System.arraycopy is faster than explicit loop as follows        */
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*      Mean length 4:  equal                                         */
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*      Mean length 8:  x2                                            */
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*      Mean length 16: x3                                            */
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*      Mean length 24: x4                                            */
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    From prior experience, we expect mean length a little below 8,  */
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    but arraycopy is still the one to use, in general, until later  */
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    measurements suggest otherwise.                                 */
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                                                                    */
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370     */
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    assembler code implementation of the algorithms below; it is    */
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    now called IXXRCN and is available with the OS/390 and VM/ESA   */
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*    operating systems.                                              */
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* ------------------------------------------------------------------ */
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* Change History:                                                    */
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.09.02 Initial version (derived from netrexx.lang classes)     */
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.09.12 Add lostDigits checking                                 */
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.10.06 Change mantissa to a byte array                         */
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.11.22 Rework power [did not prepare arguments, etc.]          */
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.12.13 multiply did not prepare arguments                      */
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1997.12.14 add did not prepare and align arguments correctly       */
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle      */
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.05.21 adjust remainder operator finalization                  */
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.06.04 rework to pass MathContext to finish() and round()      */
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.06.06 change format to use round(); support rounding modes    */
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.06.25 rename to BigDecimal and begin merge                    */
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            zero can now have trailing zeros (i.e., exp\=0)         */
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger         */
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*                         unscaledValue, valueof                     */
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.07.01 improve byteaddsub to allow array reuse, etc.           */
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32]     */
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.07.07 scaled division  [divide(BigDecimal, int, int)]         */
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.07.08 setScale, faster equals                                 */
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.10.12 change package to com.ibm.icu.math                          */
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.12.14 power operator no longer rounds RHS [to match ANSI]     */
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1998.12.29 improve byteaddsub by using table lookup                */
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.02.05 cleaner code for BigDecimal(char[])                     */
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.02.06 add javadoc comments                                    */
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.02.11 format() changed from 7 to 2 method form                */
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.03.05 null pointer checking is no longer explicit             */
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.03.05 simplify; changes from discussion with J. Bloch:        */
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            null no longer permitted for MathContext; drop boolean, */
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            byte, char, float, short constructor, deprecate double  */
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            constructor, no blanks in string constructor, add       */
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            offset and length version of char[] constructor;        */
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            add valueOf(double); drop booleanValue, charValue;      */
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*            add ...Exact versions of remaining convertors           */
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.03.13 add toBigIntegerExact                                   */
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic          */
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits  */
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.07.03 1.03 lost digits should not be checked if digits=0      */
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.07.06      lost digits Exception message changed              */
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic)             */
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.07.17      improve messages from pow method                   */
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.08.08      performance tweaks                                 */
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.08.15      fastpath in multiply                               */
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555]    */
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 1999.12.22 1.06 remove multiply fastpath, and improve performance  */
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 2000.01.01      copyright update [Y2K has arrived]                 */
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 2000.06.18 1.08 no longer deprecate BigDecimal(double)             */
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* ------------------------------------------------------------------ */
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * conversions, and hashing.
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * primitive types (which may not be exact) and <code>BigInteger</code>.
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * operation.
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br>
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <i>[This URL will change.]</i>
1282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert *
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <h3>Operator methods</h3>
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code>
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9,
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>.
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * version of each method, the context settings used are <code>digits=0,
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2.
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * current object.
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the right-hand operand.
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>extra</code> could be written as any of:
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     award.add(extra)
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>award.add(extra, MathContext.DEFAULT)
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>award.add(extra, acontext)
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code>
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code>
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * settings.
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * arithmetic documentation (see the URL above), but in summary:
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <ul>
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br>
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code>
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled)
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code>
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * parameter). <br>
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm.
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part).
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the fractional part of results). <br>
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * So, for example:
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     new BigDecimal("2.40").add(     new BigDecimal("2"))      =&gt; "4.40"
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").subtract(new BigDecimal("2"))      =&gt; "0.40"
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").multiply(new BigDecimal("2"))      =&gt; "4.80"
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").divide(  new BigDecimal("2"), def) =&gt; "1.2"
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code>
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * where the value on the right of the <code>=&gt;</code> would be the result of the operation, expressed as a
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code>
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * necessary, trailing zeros may be easily removed using division by 1.
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * will be expressed in exponential notation; thus
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *   new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code>
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * results in <code>1E+12</code> instead of <code>1000000000000</code>, and
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *   new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code>
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>.
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting.
214bee65486a185907111f3be60992433e133ec0e32Scott Russell * </ul>
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>,
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
2182d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert *
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see MathContext
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Mike Cowlishaw
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.0
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> {
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // private static final java.lang.String $0="BigDecimal.nrx";
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ----- Constants ----- */
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* properties constant public */// useful to others
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> constant "0".
2312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #ONE
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #TEN
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                      // want the int
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                      // constructor
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // .. to be able to use this, for speed
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> constant "1".
2432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #TEN
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #ZERO
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                     // want the int
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                     // constructor
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // .. to be able to use this, for speed
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> constant "10".
2552d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #ONE
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #ZERO
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10);
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // the rounding modes (copied here for upwards compatibility)
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round to a more positive number.
2652d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_CEILING
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING;
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round towards zero.
2732d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_DOWN
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN;
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round to a more negative number.
2812d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_FLOOR
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR;
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down.
2892d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_HALF_DOWN
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor.
2972d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_HALF_EVEN
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up.
3052d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_HALF_UP
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP;
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to assert that no rounding is necessary.
3132d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_UNNECESSARY
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rounding mode to round away from zero.
3212d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see MathContext#ROUND_UP
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP;
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* properties constant private */// locals
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte ispos = 1; // ind: indicates positive (must be 1)
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte iszero = 0; // ind: indicates zero (must be 0)
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte isneg = -1; // ind: indicates negative (must be -1)
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // [later could add NaN, +/- infinity, here]
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MinExp = -999999999; // minimum exponent allowed
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MaxExp = 999999999; // maximum exponent allowed
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MinArg = -999999999; // minimum argument integer
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MaxArg = 999999999; // maximum argument integer
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0,
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* properties constant private unused */// present but not referenced
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Serialization version
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final long serialVersionUID = 8245355804974198832L;
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // private static final java.lang.String
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // copyright=" Copyright (c) IBM Corporation 1996, 2000.  All rights reserved. ";
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* properties static private */
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Precalculated constant arrays (used by byteaddsub)
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static byte bytedig[] = diginit(); // next digit array
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ----- Instance properties [all private and immutable] ----- */
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* properties private */
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The indicator. This may take the values:
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <ul>
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </ul>
3612d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @serial
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private byte ind; // assumed undefined
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // We only need two bits for this, but use a byte [also permits
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // smooth future extension].
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The formatting style. This may take the values:
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <ul>
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li>
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * MathContext.ENGINEERING -- engineering notation required
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </ul>
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This property is an optimization; it allows us to defer number layout until it is actually needed as a string,
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * hence avoiding unnecessary formatting.
3782d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @serial
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // We only need two bits for this, at present, but use a byte
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // [again, to allow for smooth future extension]
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The value of the mantissa.
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Once constructed, this may become shared between several BigDecimal objects, so must not be altered.
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
390bee65486a185907111f3be60992433e133ec0e32Scott Russell     * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -&gt; 9.
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * plain number, for example, 0.000).
3942d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @serial
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private byte mant[]; // assumed null
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The exponent.
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero.
4032d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note that this property can have a value less than MinExp when the mantissa has more than one digit.
4052d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @serial
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int exp;
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // assumed 0
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* Constructors */
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>.
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The parameter must not be <code>null</code>.
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>(Note: this constructor is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class.
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * It would not be present in a <code>java.math</code> version.)</i>
4252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param bd The <code>BigDecimal</code> to be translated.
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(java.math.BigDecimal bd) {
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(bd.toString());
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code>, with scale 0.
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * with a scale of zero. The value of the <code>BigDecimal</code> is identical to the value of the <code>BigInteger
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>. The parameter must not be <code>null</code>.
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
4442d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param bi The <code>BigInteger</code> to be converted.
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(java.math.BigInteger bi) {
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(bi.toString(10));
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // exp remains 0
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code> and a scale.
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * scaled by the second parameter, which may not be negative. The value of the <code>BigDecimal</code> is the <code>
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * BigInteger</code> divided by ten to the power of the scale. The <code>BigInteger</code> parameter must not be
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>null</code>.
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> will contain only decimal digits, (with an embedded decimal point followed by <code>
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * scale</code> decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the <code>
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
4672d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param bi The <code>BigInteger</code> to be converted.
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param scale The <code>int</code> specifying the scale.
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException If the scale is negative.
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(java.math.BigInteger bi, int scale) {
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(bi.toString(10));
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (scale < 0)
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        exp = -scale; // exponent is -scale
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from an array of characters.
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>null</code>.
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * already available in character array form.
4912d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param inchars The <code>char[]</code> array containing the number to be converted.
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException If the parameter is not a valid number.
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(char inchars[]) {
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(inchars, 0, inchars.length);
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from an array of characters.
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The first parameter must not be <code>null</code>, and the subarray must be wholly contained within it.
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * already available within a character array.
5112d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param inchars The <code>char[]</code> array containing the number to be converted.
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param offset The <code>int</code> offset into the array of the start of the number to be converted.
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param length The <code>int</code> length of the number.
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException If the parameter is not a valid number for any reason.
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(char inchars[], int offset, int length) {
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super();
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean exotic;
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean hadexp;
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int d;
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dotoff;
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int last;
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char si = 0;
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean eneg = false;
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int k = 0;
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int elen = 0;
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int j = 0;
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char sj = 0;
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dvalue = 0;
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mag = 0;
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // This is the primary constructor; all incoming strings end up
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // here; it uses explicit (inline) parsing for speed and to avoid
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // generating intermediate (temporary) objects of any kind.
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1998.06.25: exponent form built only if E/e in string
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1998.06.25: trailing zeros not removed for zero
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.03.06: no embedded blanks; allow offset and length
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (length <= 0)
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            bad(inchars); // bad conversion (empty string)
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [bad offset will raise array bounds exception]
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Handle and step past sign */
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ind = ispos; // assume positive
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (inchars[offset] == ('-')) {
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            length--;
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (length == 0)
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                bad(inchars); // nothing after sign
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = isneg;
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            offset++;
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else if (inchars[offset] == ('+')) {
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            length--;
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (length == 0)
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                bad(inchars); // nothing after sign
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            offset++;
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* We're at the start of the number */
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        exotic = false; // have extra digits
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        hadexp = false; // had explicit exponent
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        d = 0; // count of digits found
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        dotoff = -1; // offset where dot was found
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        last = -1; // last character of mantissa
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $1 = length;
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = offset;
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (; $1 > 0; $1--, i++) {
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                si = inchars[i];
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (si >= '0') // test for Arabic digit
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (si <= '9') {
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        last = i;
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        d++; // still in mantissa
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        continue i;
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (si == '.') { // record and ignore
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (dotoff >= 0)
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        bad(inchars); // two dots
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    dotoff = i - offset; // offset into mantissa
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue i;
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (si != 'e')
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (si != 'E') { // expect an extra digit
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((!(UCharacter.isDigit(si))))
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            bad(inchars); // not a number
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // defer the base 10 check until later to avoid extra method call
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        exotic = true; // will need conversion later
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        last = i;
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        d++; // still in mantissa
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        continue i;
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* Found 'e' or 'E' -- now process explicit exponent */
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // 1998.07.11: sign no longer required
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((i - offset) > (length - 2))
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bad(inchars); // no room for even one digit
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                eneg = false;
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((inchars[i + 1]) == ('-')) {
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    eneg = true;
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    k = i + 2;
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if ((inchars[i + 1]) == ('+'))
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    k = i + 2;
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    k = i + 1;
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // k is offset of first expected digit
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                elen = length - ((k - offset)); // possible number of digits
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((elen == 0) | (elen > 9))
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bad(inchars); // 0 or more than 9 digits
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $2 = elen;
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    j = k;
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $2 > 0; $2--, j++) {
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        sj = inchars[j];
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (sj < '0')
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            bad(inchars); // always bad
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (sj > '9') { // maybe an exotic digit
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if ((!(UCharacter.isDigit(sj))))
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                bad(inchars); // not a number
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            dvalue = UCharacter.digit(sj, 10); // check base
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (dvalue < 0)
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                bad(inchars); // not base 10
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else
6232d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                            dvalue = ((sj)) - (('0'));
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        exp = (exp * 10) + dvalue;
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* j */
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (eneg)
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    exp = -exp; // was negative
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                hadexp = true; // remember we had one
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                break i; // we are done
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Here when all inspected */
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (d == 0)
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            bad(inchars); // no mantissa digits
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (dotoff >= 0)
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            exp = (exp + dotoff) - d; // adjust exponent if had dot
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* strip leading zeros/dot (leave final if all 0's) */
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $3 = last - 1;
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = offset;
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (; i <= $3; i++) {
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                si = inchars[i];
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (si == '0') {
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    offset++;
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    dotoff--;
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    d--;
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (si == '.') {
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    offset++; // step past dot
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    dotoff--;
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (si <= '9')
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i;/* non-0 */
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else {/* exotic */
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if ((UCharacter.digit(si, 10)) != 0)
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break i; // non-0 or bad
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // is 0 .. strip like '0'
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    offset++;
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    dotoff--;
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    d--;
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Create the mantissa array */
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mant = new byte[d]; // we know the length
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        j = offset; // input offset
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exotic) {
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do { // slow: check for exotica
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $4 = d;
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = 0;
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $4 > 0; $4--, i++) {
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (i == dotoff)
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            j++; // at dot
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        sj = inchars[j];
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (sj <= '9')
6792d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                            mant[i] = (byte) (((sj)) - (('0')));/* easy */
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        else {
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            dvalue = UCharacter.digit(sj, 10);
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (dvalue < 0)
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                bad(inchars); // not a number after all
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            mant[i] = (byte) dvalue;
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        j++;
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* exotica */
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else {
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $5 = d;
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = 0;
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $5 > 0; $5--, i++) {
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (i == dotoff)
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            j++;
6992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                        mant[i] = (byte) (((inchars[j])) - (('0')));
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        j++;
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* simple */
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Looks good. Set the sign indicator and form, as needed. */
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Trailing zeros are preserved
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // The rule here for form is:
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // If no E-notation, then request plain notation
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Otherwise act as though add(0,DEFAULT) and request scientific notation
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [form is already PLAIN]
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (mant[0] == 0) {
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = iszero; // force to show zero
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // negative exponent is significant (e.g., -3 for 0.000) if plain
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (exp > 0)
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                exp = 0; // positive exponent can be ignored
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (hadexp) { // zero becomes single digit from add
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mant = ZERO.mant;
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                exp = 0;
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else { // non-zero
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [ind was set earlier]
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // now determine form
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (hadexp) {
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC;
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // 1999.06.29 check for overflow
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mag = (exp + mant.length) - 1; // true exponent in scientific notation
7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((mag < MinExp) | (mag > MaxExp))
7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bad(inchars);
7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object directly from a <code>double</code>.
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * floating point parameter.
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note that this constructor it an exact conversion; it does not give the same result as converting <code>num
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> to a <code>String</code> using the <code>Double.toString()</code> method and then using the
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)}
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * method to construct a <code>BigDecimal</code> from a <code>double</code>.
7462d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param num The <code>double</code> to be converted.
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException If the parameter is infinite or not a number.
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(double num) {
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.03.06: use exactly the old algorithm
7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 2000.01.01: note that this constructor does give an exact result,
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // so perhaps it should not be deprecated
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 2000.06.18: no longer deprecated
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this((new java.math.BigDecimal(num)).toString());
7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object directly from a <code>int</code>.
7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 32-bit signed binary
7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
7672d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param num The <code>int</code> to be converted.
7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(int num) {
7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super();
7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mun;
7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We fastpath commoners
7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (num <= 9)
7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (num >= (-9)) {
7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                do {
7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // very common single digit case
7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    {/* select */
7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (num == 0) {
7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            mant = ZERO.mant;
7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ind = iszero;
7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else if (num == 1) {
7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            mant = ONE.mant;
7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ind = ispos;
7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else if (num == (-1)) {
7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            mant = ONE.mant;
7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ind = isneg;
7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else {
7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            {
7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                mant = new byte[1];
7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                if (num > 0) {
7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    mant[0] = (byte) num;
7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    ind = ispos;
7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                } else { // num<-1
7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    mant[0] = (byte) -num;
7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    ind = isneg;
8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                }
8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return;
8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } while (false);
8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* singledigit */
8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* We work on negative numbers so we handle the most negative number */
8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (num > 0) {
8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = ispos;
8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            num = -num;
8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else
8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = isneg;/* negative */// [0 case already handled]
8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [it is quicker, here, to pre-calculate the length with
8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // one loop, then allocate exactly the right length of byte array,
8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // then re-fill it with another loop]
8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mun = num; // working copy
8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 9;
8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (;; i--) {
8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mun = mun / 10;
8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (mun == 0)
8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i;
8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // i is the position of the leftmost digit placed
8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mant = new byte[10 - i];
8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = (10 - i) - 1;
8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (;; i--) {
8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mant[i] = (byte) -(((byte) (num % 10)));
8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                num = num / 10;
8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (num == 0)
8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i;
8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object directly from a <code>long</code>.
8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
8462d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param num The <code>long</code> to be converted.
8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(long num) {
8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super();
8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long mun;
8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Not really worth fastpathing commoners in this constructor [also,
8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // we use this to construct the static constants].
8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // This is much faster than: this(String.valueOf(num).toCharArray())
8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* We work on negative num so we handle the most negative number */
8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (num > 0) {
8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = ispos;
8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            num = -num;
8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else if (num == 0)
8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = iszero;
8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = isneg;/* negative */
8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mun = num;
8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 18;
8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (;; i--) {
8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mun = mun / 10;
8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (mun == 0)
8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i;
8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // i is the position of the leftmost digit placed
8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mant = new byte[19 - i];
8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = (19 - i) - 1;
8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (;; i--) {
8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mant[i] = (byte) -(((byte) (num % 10)));
8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                num = num / 10;
8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (num == 0)
8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i;
8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>BigDecimal</code> from the parameter, which must not be <code>null</code> and must represent a
8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * valid <i>number</i>, as described formally in the documentation referred to {@link BigDecimal above}.
8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * In summary, numbers in <code>String</code> form must have at least one digit, may have a leading sign, may have a
8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks.
8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Some valid strings from which a <code>BigDecimal</code> might be constructed are:
8992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <pre>
9012d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Exponential notation
9052d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </pre>
9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (Exponential notation means that the number includes an optional sign and a power of ten following an
909bee65486a185907111f3be60992433e133ec0e32Scott Russell     * '<code>E</code>' that indicates how the decimal point will be shifted. Thus the <code>"4E+9"</code> above is
9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * just a short way of writing <code>4000000000</code>, and the <code>"0.73e-7"</code> is short for <code>
9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 0.000000073</code>.)
9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The <code>BigDecimal</code> constructed from the String is in a standard form, with no blanks, as though the
9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string
9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * uses exponential notation (that is, includes an <code>e</code> or an <code>E</code>), then the <code>BigDecimal
9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> number will be expressed in scientific notation (where the power of ten is adjusted so there is a single
9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as
9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must
9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * fit in nine digits both before and after it is expressed in scientific notation.
9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
921bee65486a185907111f3be60992433e133ec0e32Scott Russell     * Any digits in the parameter must be decimal; that is, <code>Character.digit(c, 10)</code> (where <code>c</code>
9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * is the character in question) would not return -1.
9232d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param string The <code>String</code> to be converted.
9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException If the parameter is not a valid number.
9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BigDecimal(java.lang.String string) {
9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(string.toCharArray(), 0, string.length());
9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* <sgml> Make a default BigDecimal object for local use. </sgml> */
9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private BigDecimal() {
9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super();
9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return;
9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* Operator methods [methods which take a context parameter] */
9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #abs(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be <code>this.scale()</code>
9512d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
9537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal abs() {
9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.abs(plainMC);
9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method
9647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)}
9657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * method with the same parameter is returned.
9662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
9697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) {
9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (this.ind == isneg)
9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return this.negate(set);
9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.plus(set);
9767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
9852d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) {
9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.add(rhs, plainMC);
9937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
9977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
9987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the addition (<b><code>+</code></b>) operator (as defined in the decimal documentation, see
9997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
10002d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
10017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
10027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
10037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>.
10047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
10057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
10087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal lhs;
10097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int reqdig;
10107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
10117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte usel[];
10127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int usellen;
10137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte user[];
10147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int userlen;
10157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newlen = 0;
10167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int tlen = 0;
10177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mult = 0;
10187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte t[] = null;
10197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ia = 0;
10207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ib = 0;
10217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ea = 0;
10227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int eb = 0;
10237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte ca = 0;
10247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte cb = 0;
10257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* determine requested digits and form */
10267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
10277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
10287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lhs = this; // name for clarity and proxy
10297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Quick exit for add floating 0 */
10317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // plus() will optimize to return same object if possible
10327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (lhs.ind == 0)
10337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
10347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return rhs.plus(set);
10357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rhs.ind == 0)
10367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
10377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return lhs.plus(set);
10387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Prepare numbers (round, unless unlimited precision) */
10407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        reqdig = set.digits; // local copy (heavily used)
10417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reqdig > 0) {
10427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lhs.mant.length > reqdig)
10437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                lhs = clone(lhs).round(set);
10447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rhs.mant.length > reqdig)
10457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rhs = clone(rhs).round(set);
10467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [we could reuse the new LHS for result in this case]
10477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = new com.ibm.icu.math.BigDecimal(); // build result here
10507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
10527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much
10537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to
10547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * DIGITS trailing zeros].
10557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
10567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Note sign may be 0 if digits (reqdig) is 0
10577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // usel and user will be the byte arrays passed to the adder; we'll
10587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // use them on all paths except quick exits
10597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        usel = lhs.mant;
10607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        usellen = lhs.mant.length;
10617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        user = rhs.mant;
10627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        userlen = rhs.mant.length;
10637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
10647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {/* select */
10657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (lhs.exp == rhs.exp) {/* no padding needed */
10667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // This is the most common, and fastest, path
10677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = lhs.exp;
10687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs
10697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newlen = (usellen + lhs.exp) - rhs.exp;
10707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    /*
10717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot
10727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     * affect answer, so we only need to pad up to a length of DIGITS+1.
10737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     */
10747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen >= ((userlen + reqdig) + 1))
10757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (reqdig > 0) {
10767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // LHS is sufficient
10777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.mant = usel;
10787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.exp = lhs.exp;
10797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.ind = lhs.ind;
10807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (usellen < reqdig) { // need 0 padding
10817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                res.mant = extend(lhs.mant, reqdig);
10827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                res.exp = res.exp - ((reqdig - usellen));
10837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
10847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return res.finish(set, false);
10857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
10867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // RHS may affect result
10877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = rhs.exp; // expected final exponent
10887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen > (reqdig + 1))
10897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (reqdig > 0) {
10907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // LHS will be max; RHS truncated
10917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            tlen = (newlen - reqdig) - 1; // truncation length
10927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            userlen = userlen - tlen;
10937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.exp = res.exp + tlen;
10947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            newlen = reqdig + 1;
10957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
10967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen > usellen)
10977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        usellen = newlen; // need to pad LHS
10987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else { // need to pad rhs and/or truncate lhs
10997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newlen = (userlen + rhs.exp) - lhs.exp;
11007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen >= ((usellen + reqdig) + 1))
11017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (reqdig > 0) {
11027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // RHS is sufficient
11037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.mant = user;
11047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.exp = rhs.exp;
11057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.ind = rhs.ind;
11067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (userlen < reqdig) { // need 0 padding
11077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                res.mant = extend(rhs.mant, reqdig);
11087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                res.exp = res.exp - ((reqdig - userlen));
11097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
11107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return res.finish(set, false);
11117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
11127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // LHS may affect result
11137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = lhs.exp; // expected final exponent
11147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen > (reqdig + 1))
11157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (reqdig > 0) {
11167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // RHS will be max; LHS truncated
11177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            tlen = (newlen - reqdig) - 1; // truncation length
11187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            usellen = usellen - tlen;
11197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.exp = res.exp + tlen;
11207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            newlen = reqdig + 1;
11217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
11227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newlen > userlen)
11237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        userlen = newlen; // need to pad RHS
11247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
11257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
11267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* padder */
11277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* OK, we have aligned mantissas. Now add or subtract. */
11297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
11307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
11317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
11327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (lhs.ind == iszero)
11337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.ind = ispos;
11347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
11357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.ind = lhs.ind; // likely sign, all paths
11367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative
11377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mult = 1;
11387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else {
11397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do { // different signs, so subtraction is needed
11407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mult = -1; // will cause subtract
11417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /*
11427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 * Before we can subtract we must determine which is the larger, as our add/subtract routine only
11437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 * handles non-negative results so we may need to swap the operands.
11447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 */
11457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
11467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    do {/* select */
11477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (rhs.ind == iszero) {
11487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // original A bigger
11497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger
11507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            t = usel;
11517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            usel = user;
11527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            user = t; // swap
11537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            tlen = usellen;
11547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            usellen = userlen;
11557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            userlen = tlen; // ..
11567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.ind = (byte) -res.ind; // and set sign
11577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else if (usellen > userlen) {
11587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // original A bigger
11597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else {
11607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            {/* logical lengths the same */// need compare
11617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                /* may still need to swap: compare the strings */
11627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                ia = 0;
11637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                ib = 0;
11647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                ea = usel.length - 1;
11657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                eb = user.length - 1;
11667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                {
11677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    compare: for (;;) {
11687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        if (ia <= ea)
11697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            ca = usel[ia];
11707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        else {
11717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            if (ib > eb) {/* identical */
11727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                if (set.form != com.ibm.icu.math.MathContext.PLAIN)
11737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    return ZERO;
11747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                // [if PLAIN we must do the subtract, in case of 0.000 results]
11757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                break compare;
11767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            }
11777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            ca = (byte) 0;
11787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        }
11797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        if (ib <= eb)
11807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            cb = user[ib];
11817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        else
11827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            cb = (byte) 0;
11837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        if (ca != cb) {
11847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            if (ca < cb) {/* swap needed */
11857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                t = usel;
11867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                usel = user;
11877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                user = t; // swap
11887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                tlen = usellen;
11897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                usellen = userlen;
11907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                userlen = tlen; // ..
11917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                res.ind = (byte) -res.ind;
11927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            }
11937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            break compare;
11947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        }
11957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        /* mantissas the same, so far */
11967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        ia++;
11977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        ib++;
11987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    }
11997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                }/* compare */
12007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            } // lengths the same
12017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
12027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } while (false);
12037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* swaptest */
12047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
12057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* signdiff */
12067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* here, A is > B if subtracting */
12087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // add [A+B*1] or subtract [A+(B*-1)]
12097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.mant = byteaddsub(usel, usellen, user, userlen, mult, false);
12107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [reuse possible only after chop; accounting makes not worthwhile]
12117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Finish() rounds before stripping leading 0's, then sets form, etc.
12137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(set, false);
12147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
12157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
12177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Compares this <code>BigDecimal</code> to another, using unlimited precision.
12187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
12197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #compareTo(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
12207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
12212d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
12227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
12237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
12247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         or greater than <code>rhs</code>.
12257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
12267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
12277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
12297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int compareTo(com.ibm.icu.math.BigDecimal rhs) {
12307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.compareTo(rhs, plainMC);
12317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
12327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
12347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Compares this <code>BigDecimal</code> to another.
12357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
12367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}),
12377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and returns a result of type <code>int</code>.
12387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
12397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The result will be:
12407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <table cellpadding=2>
12417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <tr>
12427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <td align=right><b>-1</b></td> <td>if the current object is less than the first parameter</td>
12437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </tr>
12447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <tr>
12457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <td align=right><b>0</b></td> <td>if the current object is equal to the first parameter</td>
12467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </tr>
12477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <tr>
12487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <td align=right><b>1</b></td> <td>if the current object is greater than the first parameter.</td>
12497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </tr>
12507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </table>
12517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
12527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * A {@link #compareTo(BigDecimal)} method is also provided.
12532d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
12547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
12557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
12567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
12577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         or greater than <code>rhs</code>.
12587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
12597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
12607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
12627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int thislength = 0;
12637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
12647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal newrhs;
12657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // rhs=null will raise NullPointerException, as per Comparable interface
12667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
12677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
12687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [add will recheck in slowpath cases .. but would report -rhs]
12697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) {
12707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* sign & exponent the same [very common] */
12717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            thislength = this.mant.length;
12727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thislength < rhs.mant.length)
12737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return (byte) -this.ind;
12747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thislength > rhs.mant.length)
12757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return this.ind;
12767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /*
12777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very
12787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             * unusual]
12797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             */
12807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((thislength <= set.digits) | (set.digits == 0)) {
12817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
12827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $6 = thislength;
12837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = 0;
12847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $6 > 0; $6--, i++) {
12857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (this.mant[i] < rhs.mant[i])
12867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return (byte) -this.ind;
12877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (this.mant[i] > rhs.mant[i])
12887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return this.ind;
12897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
12907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
12917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return 0; // identical
12927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
12937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* drop through for full comparison */
12947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
12957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* More fastpaths possible */
12967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this.ind < rhs.ind)
12977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return -1;
12987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this.ind > rhs.ind)
12997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return 1;
13007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
13017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* carry out a subtract to make the comparison */
13027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newrhs = clone(rhs); // safe copy
13037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
13047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.add(newrhs, set).ind; // add, and return sign of result
13057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
13087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
13097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #divide(BigDecimal, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
13117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * rounding mode is {@link MathContext#ROUND_HALF_UP}.
13122d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
13137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
13147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the latter were formatted without exponential notation.
13152d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
13167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
13177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
13187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException If <code>rhs</code> is zero.
13197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
13207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
13217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) {
13237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('D', rhs, plainMC, -1);
13247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
13277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
13287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * rounding mode.
13297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #divide(BigDecimal, int, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
13317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * second parameter is <code>this.scale()</code>, and the third is <code>round</code>.
13327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current
13347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * object, if the latter were formatted without exponential notation.
13357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13362d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
13377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
13387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
13397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
13407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         the specified rounding mode.
13417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
13427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
13437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>this.scale()</code> is insufficient to represent the result exactly.
13447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
13457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
13467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) {
13487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.MathContext set;
13497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round,
13507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                     // too]
13517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('D', rhs, set, -1); // take scale from LHS
13527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
13557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
13567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * given scale and rounding mode.
13577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #divide(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
13597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>, except that the length of the decimal part (the
13607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * scale) to be used for the result is explicit rather than being taken from <code>this</code>.
13617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
13637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the latter were formatted without exponential notation.
13647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13652d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
13667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
13677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param scale The <code>int</code> scale to be used for the result.
13687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
13697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
13707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         the specified rounding mode.
13717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
13727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
13737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>scale</code> is negative.
13747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>scale</code> is insufficient
13757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *             to represent the result exactly.
13767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
13777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
13787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) {
13807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.MathContext set;
13817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (scale < 0)
13827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
13837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round]
13847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('D', rhs, set, scale);
13857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
13887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
13897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
13907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the division (<b><code>/</code></b>) operator (as defined in the decimal documentation, see
13917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
13922d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
13937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
13947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
13957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this/rhs</code>.
13967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
13977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
13987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
13997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
14017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('D', rhs, set, -1);
14027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
14067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs
14087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>, and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
14092d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
14107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
14117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
14127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
14137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
14147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
14157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) {
14177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // scale 0 to drop .000 when plain
14187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('I', rhs, plainMC, 0);
14197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
14237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class
14257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * header}), and returns the result as a <code>BigDecimal</code> object.
14262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
14277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
14287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
14297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
14307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
14317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if the result will not fit in the number of digits specified for the context.
14327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
14337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
14347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
14367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // scale 0 to drop .000 when plain
14377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('I', rhs, set, 0);
14387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
14427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #max(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
14447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
14452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
14467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
14477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
14487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
14497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
14507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) {
14527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.max(rhs, plainMC);
14537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
14577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the larger of the current object and the first parameter.
14597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>1
14617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
14627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
14637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
14647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * parameter) is returned.
14652d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
14667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
14677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
14687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
14697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
14707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
14717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
14737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((this.compareTo(rhs, set)) >= 0)
14747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return this.plus(set);
14757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
14767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rhs.plus(set);
14777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
14817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #min(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
14837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
14842d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
14857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
14867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
14877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
14887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
14897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) {
14917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.min(rhs, plainMC);
14927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
14957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
14967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the smaller of the current object and the first parameter.
14987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
14997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>-1
15007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
15017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
15027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
15037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * parameter) is returned.
15042d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
15057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
15067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
15077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
15087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
15097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
15107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
15127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((this.compareTo(rhs, set)) <= 0)
15137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return this.plus(set);
15147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
15157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rhs.plus(set);
15167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
15177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
15197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
15207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
15217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
15227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
15237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
15247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they
15257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * were formatted without exponential notation.
15262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
15277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
15287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
15297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
15307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
15317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) {
15337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.multiply(rhs, plainMC);
15347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
15357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
15377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
15387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
1539bee65486a185907111f3be60992433e133ec0e32Scott Russell     * Implements the multiplication (<b><code>&#42;</code></b>) operator (as defined in the decimal documentation, see
15407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
15412d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
15427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
15437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
15447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>.
15457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
15467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
15477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
15497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal lhs;
15507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int padding;
15517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int reqdig;
15527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte multer[] = null;
15537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte multand[] = null;
15547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int multandlen;
15557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int acclen = 0;
15567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
15577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte acc[];
15587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int n = 0;
15597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte mult = 0;
15607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
15617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
15627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lhs = this; // name for clarity and proxy
15637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Prepare numbers (truncate, unless unlimited precision) */
15657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        padding = 0; // trailing 0's to add
15667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        reqdig = set.digits; // local copy
15677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reqdig > 0) {
15687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lhs.mant.length > reqdig)
15697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                lhs = clone(lhs).round(set);
15707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rhs.mant.length > reqdig)
15717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rhs = clone(rhs).round(set);
15727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [we could reuse the new LHS for result in this case]
15737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* unlimited */
15747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // fixed point arithmetic will want every trailing 0; we add these
15757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // after the calculation rather than before, for speed.
15767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lhs.exp > 0)
15777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                padding = padding + lhs.exp;
15787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rhs.exp > 0)
15797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                padding = padding + rhs.exp;
15807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
15817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // For best speed, as in DMSRCN, we use the shorter number as the
15837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // multiplier and the longer as the multiplicand.
15847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.12.22: We used to special case when the result would fit in
15857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // a long, but with Java 1.3 this gave no advantage.
15867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (lhs.mant.length < rhs.mant.length) {
15877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            multer = lhs.mant;
15887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            multand = rhs.mant;
15897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
15907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            multer = rhs.mant;
15917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            multand = lhs.mant;
15927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
15937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Calculate how long result byte array will be */
15957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        multandlen = (multer.length + multand.length) - 1; // effective length
15967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // optimize for 75% of the cases where a carry is expected...
15977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((multer[0] * multand[0]) > 9)
15987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            acclen = multandlen + 1;
15997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
16007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            acclen = multandlen;
16017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Now the main long multiplication loop */
16037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
16047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        acc = new byte[acclen]; // accumulator, all zeros
16057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1998.07.01: calculate from left to right so that accumulator goes
16067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // to likely final length on first addition; this avoids a one-digit
16077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // extension (and object allocation) each time around the loop.
16087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Initial number therefore has virtual zeros added to right.
16097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
16107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $7 = multer.length;
16117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            n = 0;
16127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; $7 > 0; $7--, n++) {
16137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                mult = multer[n];
16147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (mult != 0) { // [optimization]
16157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // accumulate [accumulator is reusable array]
16167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true);
16177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // divide multiplicand by 10 for next digit to right
16197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                multandlen--; // 'virtual length'
16207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* n */
16227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.ind = (byte) (lhs.ind * rhs.ind); // final sign
16247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.exp = (lhs.exp + rhs.exp) - padding; // final exponent
16257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [overflow is checked by finish]
16267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* add trailing zeros to the result, if necessary */
16287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (padding == 0)
16297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.mant = acc;
16307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
16317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.mant = extend(acc, acc.length + padding); // add trailing 0s
16327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(set, false);
16337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
16347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
16367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>-this</code>.
16377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #negate(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>
16397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * .
16407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
16422d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
16432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
16447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
16457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
16467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
16477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal negate() {
16497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.negate(plainMC);
16507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
16517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
16537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
16547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the negation (Prefix <b><code>-</code></b>) operator (as defined in the decimal documentation, see
16567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
16572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
16587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
16597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
16607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
16617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
16627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) {
16647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
16657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Originally called minus(), changed to matched Java precedents
16667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // This simply clones, flips the sign, and possibly rounds
16677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
16687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
16697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = clone(this); // safe copy
16707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.ind = (byte) -res.ind;
16717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(set, false);
16727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
16737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
16757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>+this</code>. Note that <code>this</code> is not
16767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * necessarily a plain <code>BigDecimal</code>, but the result will always be.
16777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #plus(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
16797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
16812d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
16827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
16837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
16847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
16857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal plus() {
16877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.plus(plainMC);
16887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
16897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
16917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>+this</code>.
16927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the plus (Prefix <b><code>+</code></b>) operator (as defined in the decimal documentation, see
16947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
16957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
16967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This method is useful for rounding or otherwise applying a context to a decimal value.
16972d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
16987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
16997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
17007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
17017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
17027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) {
17047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // This clones and forces the result to the new settings
17057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // May return same object
17067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
17077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
17087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Optimization: returns same object for some common cases
17097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.form == com.ibm.icu.math.MathContext.PLAIN)
17107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this.form == com.ibm.icu.math.MathContext.PLAIN) {
17117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (this.mant.length <= set.digits)
17127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return this;
17137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (set.digits == 0)
17147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return this;
17157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
17167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return clone(this).finish(set, false);
17177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
17187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
17207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
17217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
17227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #pow(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
17237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
17247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
17257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The parameter is the power to which the <code>this</code> will be raised; it must be in the range 0 through
17267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so
17277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * they should not be used as a test for a whole number.
17287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
17297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * In addition, the power must not be negative, as no <code>MathContext</code> is used and so the result would then
17307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * always be 0.
17312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
17327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
17337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
17347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
17357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
17367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
17377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) {
17397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.pow(rhs, plainMC);
17407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
17417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // The name for this method is inherited from the precedent set by the
17437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // BigInteger and Math classes.
17447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
17467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
17477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
1748bee65486a185907111f3be60992433e133ec0e32Scott Russell     * Implements the power (<b><code>^</code></b>) operator (as defined in the decimal documentation, see
17497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
17507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
17517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The first parameter is the power to which the <code>this</code> will be raised; it must be in the range
17527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed
17537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the future, so they should not be used as a test for a whole number.
17547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
17557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the <code>digits</code> setting of the <code>MathContext</code> parameter is 0, the power must be zero or
17567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * positive.
17572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
17587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
17597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
17607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>.
17617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
17627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
17637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
17647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
17667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int n;
17677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal lhs;
17687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int reqdig;
17697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int workdigits = 0;
17707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int L = 0;
17717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.MathContext workset;
17727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
17737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean seenbit;
17747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
17757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
17767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
17777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules
17787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lhs = this; // clarified name
17797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        reqdig = set.digits; // local copy (heavily used)
17817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reqdig == 0) {
17827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rhs.ind == isneg)
17837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString());
17847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            workdigits = 0;
17857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* non-0 digits */
17867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((rhs.mant.length + rhs.exp) > reqdig)
17877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
17887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* Round the lhs to DIGITS if need be */
17907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lhs.mant.length > reqdig)
17917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                lhs = clone(lhs).round(set);
17927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* L for precision calculation [see ANSI X3.274-1996] */
17947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp
17957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            workdigits = (reqdig + L) + 1; // calculate the working DIGITS
17967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
17977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Create a copy of set for working settings */
17997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Note: no need to check for lostDigits again.
18007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1999.07.17 Note: this construction must follow RHS check
18017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode);
18027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = ONE; // accumulator
18047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (n == 0)
18057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return res; // x**0 == 1
18067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (n < 0)
18077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            n = -n; // [rhs.ind records the sign]
18087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        seenbit = false; // set once we've seen a 1-bit
18097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
18107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 1;
18117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i: for (;; i++) { // for each bit [top bit ignored]
18127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                n = n + n; // shift left 1 bit
18137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (n < 0) { // top bit is set
18147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    seenbit = true; // OK, we're off
18157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res = res.multiply(lhs, workset); // acc=acc*x
18167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
18177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (i == 31)
18187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break i; // that was the last bit
18197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((!seenbit))
18207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue i; // we don't have to square 1
18217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = res.multiply(res, workset); // acc=acc*acc [square]
18227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
18237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */// 32 bits
18247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rhs.ind < 0) // was a **-n [hence digits>0]
18257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res = ONE.divide(res, workset); // .. so acc=1/acc
18267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(set, true); // round and strip [original digits]
18277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
18307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
18317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * arithmetic.
18327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #remainder(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
18347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
18357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This is not the modulo operator -- the result may be negative.
18372d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
18387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
18397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
18407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         arithmetic.
18417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
18427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
18437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) {
18467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('R', rhs, plainMC, -1);
18477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
18507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>.
18517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}),
18537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and returns the result as a <code>BigDecimal</code> object.
18547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This is not the modulo operator -- the result may be negative.
18562d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
18577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
18587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
18597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this+rhs</code>.
18607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>rhs</code> is zero.
18617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException  if the integer part of the result will not fit in the number of digits specified for the context.
18627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
18637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
18667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.dodivide('R', rhs, set, -1);
18677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
18707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
18717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #subtract(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
18737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
18747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
18762d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
18777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
18787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
18797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
18807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) {
18837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.subtract(rhs, plainMC);
18847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
18877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
18887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
18897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Implements the subtraction (<b><code>-</code></b>) operator (as defined in the decimal documentation, see
18907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
18912d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
18927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
18937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param set The <code>MathContext</code> arithmetic settings.
18947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>.
18957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
18967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
18997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal newrhs;
19007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
19017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
19027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [add will recheck .. but would report -rhs]
19037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* carry out the subtraction */
19047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // we could fastpath -0, but it is too rare.
19057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newrhs = clone(rhs); // safe copy
19067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
19077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.add(newrhs, set); // arithmetic
19087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
19117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* Other methods */
19127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
19137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
19157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>byte</code>. If the <code>BigDecimal</code> has a non-zero
19167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part or is out of the possible range for a <code>byte</code> (8-bit signed integer) result then an <code>
19177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ArithmeticException</code> is thrown.
19182d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
19197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>byte</code> equal in value to <code>this</code>.
19207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>byte</code>.
19217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
19227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
19237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public byte byteValueExact() {
19257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int num;
19267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        num = this.intValueExact(); // will check decimal part too
19277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((num > 127) | (num < (-128)))
19287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
19297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return (byte) num;
19307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
19337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>double</code>. If the <code>BigDecimal</code> is out of the
19347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * possible range for a <code>double</code> (64-bit signed floating point) result then an <code>ArithmeticException
19357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> is thrown.
19367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
19377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The double produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
19387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * then converting it using the <code>Double(String)</code> constructor; this can result in values of <code>
19397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Double.NEGATIVE_INFINITY</code> or <code>Double.POSITIVE_INFINITY</code>.
19402d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
19417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>double</code> corresponding to <code>this</code>.
19427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
19437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
19447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
19467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public double doubleValue() {
19477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We go via a String [as does BigDecimal in JDK 1.2]
19487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Next line could possibly raise NumberFormatException
19497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return java.lang.Double.valueOf(this.toString()).doubleValue();
19507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
19537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Compares this <code>BigDecimal</code> with <code>rhs</code> for equality.
19547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
19557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the parameter is <code>null</code>, or is not an instance of the BigDecimal type, or is not exactly equal to
19567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the current <code>BigDecimal</code> object, then <i>false</i> is returned. Otherwise, <i>true</i> is returned.
19577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
19587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * "Exactly equal", here, means that the <code>String</code> representations of the <code>BigDecimal</code> numbers
19597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * are identical (they have the same characters in the same sequence).
19607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
19617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons.
19622d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
19637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param obj The <code>Object</code> for the right hand side of the comparison.
19647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>boolean</code> whose value <i>true</i> if and only if the operands have identical string
19657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         representations.
19667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ClassCastException if <code>rhs</code> cannot be cast to a <code>BigDecimal</code> object.
19677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
19687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #compareTo(BigDecimal)
19697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #compareTo(BigDecimal, MathContext)
19707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
19717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19722d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
19737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public boolean equals(java.lang.Object obj) {
19747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal rhs;
19757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
19767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char lca[] = null;
19777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char rca[] = null;
19787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We are equal iff toString of both are exactly the same
19797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (obj == null)
19807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return false; // not equal
19817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
19827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return false; // not a decimal
19837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work
19847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (this.ind != rhs.ind)
19857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return false; // different signs never match
19867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form))
19877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { // mantissas say all
19897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // here with equal-length byte arrays to compare
19907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
19917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $8 = this.mant.length;
19927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                i = 0;
19937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (; $8 > 0; $8--, i++) {
19947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (this.mant[i] != rhs.mant[i])
19957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return false;
19967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
19977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* i */
19987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else { // need proper layout
19997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            lca = this.layout(); // layout to character array
20007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rca = rhs.layout();
20017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lca.length != rca.length)
20027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false; // mismatch
20037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // here with equal-length character arrays to compare
20047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
20057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $9 = lca.length;
20067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                i = 0;
20077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (; $9 > 0; $9--, i++) {
20087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (lca[i] != rca[i])
20097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return false;
20107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* i */
20127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
20137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return true; // arrays have identical content
20147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
20157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
20177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>float</code>. If the <code>BigDecimal</code> is out of the
20187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * possible range for a <code>float</code> (32-bit signed floating point) result then an <code>ArithmeticException
20197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> is thrown.
20207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The float produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
20227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * then converting it using the <code>Float(String)</code> constructor; this can result in values of <code>
20237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Float.NEGATIVE_INFINITY</code> or <code>Float.POSITIVE_INFINITY</code>.
20242d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
20257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>float</code> corresponding to <code>this</code>.
20267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
20277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
20287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
20307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public float floatValue() {
20317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return java.lang.Float.valueOf(this.toString()).floatValue();
20327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
20337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
20357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters.
20367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
20387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
20397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
20407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
20417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </i>
20427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The parameters, for both forms of the <code>format</code> method are all of type <code>int</code>. A value of -1
20447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for any parameter indicates that the default action or value for that parameter should be used.
20457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The parameters, <code>before</code> and <code>after</code>, specify the number of characters to be used for the
20477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter
20487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed
20497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for that part.
20507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>before</code> must be a positive number; if it is larger than is needed to contain the integer part, that
20527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * part is padded on the left with blanks to the requested length. If <code>before</code> is not large enough to
20537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown.
20547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>after</code> must be a non-negative number; if it is not the same size as the decimal part of the number,
20567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the number will be rounded (or extended with zeros) to fit. Specifying 0 for <code>after</code> will cause the
20577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method
20587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * will be the default, <code>MathContext.ROUND_HALF_UP</code>.
20597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Other rounding methods, and the use of exponential notation, can be selected by using
20617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect
20627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * as using the six-parameter form with the final four parameters all being -1.
20632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
20647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as are needed'.
20657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as are needed'.
20667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified parameters
20677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if the number cannot be laid out as requested.
20687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IllegalArgumentException if a parameter is out of range.
20697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
20707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #toString
20717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #toCharArray
20727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
20737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.lang.String format(int before, int after) {
20757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP);
20767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
20777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
20797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters and
20807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * allowing exponential notation.
20817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
20837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
20847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
20857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
20867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </i>
20877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The parameters are all of type <code>int</code>. A value of -1 for any parameter indicates that the default
20897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * action or value for that parameter should be used.
20907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The first two parameters (<code>before</code> and <code>after</code>) specify the number of characters to be used
20927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If
20937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many
20947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * as are needed for that part.
20957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
20967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The remaining parameters control the use of exponential notation and rounding. Three (<code>explaces</code>,
20977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>exdigits</code>, and <code>exform</code>) control the exponent part of the result. As before, the default
20987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * action for any of these parameters may be selected by using the value -1.
20997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
21007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>explaces</code> must be a positive number; it sets the number of places (digits after the sign of the
21017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * exponent) to be used for any exponent part, the default (when <code>explaces</code> is -1) being to use as many
21027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * as are needed. If <code>explaces</code> is not -1, space is always reserved for an exponent; if one is not needed
2103bee65486a185907111f3be60992433e133ec0e32Scott Russell     * (for example, if the exponent will be 0) then <code>explaces</code>+2 blanks are appended to the result.
2104bee65486a185907111f3be60992433e133ec0e32Scott Russell     * (This preserves vertical alignment of similarly formatted numbers in a monospace font.) If <code>explaces
21057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code> is not -1 and is not large enough to contain the exponent, an exception is thrown.
21067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
21077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>exdigits</code> sets the trigger point for use of exponential notation. If, before any rounding, the number
21087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * of places needed before the decimal point exceeds <code>exdigits</code>, or if the absolute value of the result
21097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * is less than <code>0.000001</code>, then exponential form will be used, provided that <code>exdigits</code> was
21107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * specified. When <code>exdigits</code> is -1, exponential notation will never be used. If 0 is specified for
21117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>exdigits</code>, exponential notation is always used unless the exponent would be 0.
21127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
21137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>exform</code> sets the form for exponential notation (if needed). It may be either
21147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested,
21157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * up to three digits (plus sign, if negative) may be needed for the integer part of the result (<code>before</code>
21167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ). Otherwise, only one digit (plus sign, if negative) is needed.
21177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
21187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Finally, the sixth argument, <code>exround</code>, selects the rounding algorithm to be used, and must be one of
21197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the values indicated by a public constant in the {@link MathContext} class whose name starts with <code>ROUND_
21207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>. The default (<code>ROUND_HALF_UP</code>) may also be selected by using the value -1, as before.
21217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
21227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be used to detect whether non-zero digits are
21237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * discarded -- if <code>exround</code> has this value than if non-zero digits would be discarded (rounded) during
21247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * formatting then an <code>ArithmeticException</code> is thrown.
21252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
21267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as
21277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            are needed'.
21287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as
21297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            are needed'.
21307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param explaces The <code>int</code> specifying the number of places to be used for any exponent. Use -1 for 'as many
21317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            as are needed'.
21327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param exdigits The <code>int</code> specifying the trigger (digits before the decimal point) which if exceeded causes
21337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation
21347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            (no exponential notation).
21357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param exformint The <code>int</code> specifying the form of exponential notation to be used (
21367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}).
21377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param exround The <code>int</code> specifying the rounding mode to use. Use -1 for the default,
21387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *            {@link MathContext#ROUND_HALF_UP}.
21397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified
21407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         parameters
21417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if the number cannot be laid out as requested.
21427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IllegalArgumentException if a parameter is out of range.
21437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #toString
21447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #toCharArray
21457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
21467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
21477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) {
21497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal num;
21507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mag = 0;
21517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int thisafter = 0;
21527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int lead = 0;
21537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newmant[] = null;
21547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int chop = 0;
21557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int need = 0;
21567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int oldexp = 0;
21577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char a[];
21587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int p = 0;
21597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char newa[] = null;
21607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
21617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int places = 0;
21627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Check arguments */
21647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((before < (-1)) | (before == 0))
21657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            badarg("format", 1, java.lang.String.valueOf(before));
21667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (after < (-1))
21677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            badarg("format", 2, java.lang.String.valueOf(after));
21687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((explaces < (-1)) | (explaces == 0))
21697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            badarg("format", 3, java.lang.String.valueOf(explaces));
21707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exdigits < (-1))
21717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            badarg("format", 4, java.lang.String.valueOf(explaces));
21727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/* select */
21737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) {
21747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) {
21757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (exformint == (-1))
21767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                exformint = com.ibm.icu.math.MathContext.SCIENTIFIC;
21777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // note PLAIN isn't allowed
21787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
21797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                badarg("format", 5, java.lang.String.valueOf(exformint));
21807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
21827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // checking the rounding mode is done by trying to construct a
21837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // MathContext object with that mode; it will fail if bad
21847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exround != ROUND_HALF_UP) {
21857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try { // if non-default...
21867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (exround == (-1))
21877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    exround = ROUND_HALF_UP;
21887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else
21897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround);
21907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (java.lang.IllegalArgumentException $10) {
21917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                badarg("format", 6, java.lang.String.valueOf(exround));
21927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
21947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        num = clone(this); // make private copy
21967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
21987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0]
21997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two]
22007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified
22017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
22027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* determine form */
22047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
22057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {/* select */
22067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (exdigits == (-1))
22077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
22087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else if (num.ind == iszero)
22097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
22107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else {
22117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // determine whether triggers
22127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    mag = num.exp + num.mant.length;
22137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (mag > exdigits)
22147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        num.form = (byte) exformint;
22157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else if (mag < (-5))
22167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        num.form = (byte) exformint;
22177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else
22187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
22197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
22217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* setform */
22227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
22247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform
22257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific).
22267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
22277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (after >= 0) {
22287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            setafter: for (;;) {
22297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // calculate the current after-length
22307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {/* select */
22317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (num.form == com.ibm.icu.math.MathContext.PLAIN)
22327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        thisafter = -num.exp; // has decimal part
22337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC)
22347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        thisafter = num.mant.length - 1;
22357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else { // engineering
22367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use
22377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (lead < 0)
22387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            lead = 3 + lead; // negative exponent case
22397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        lead++; // number of leading digits
22407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (lead >= num.mant.length)
22417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            thisafter = 0;
22427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        else
22437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            thisafter = num.mant.length - lead;
22447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
22457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (thisafter == after)
22477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break setafter; // we're in luck
22487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (thisafter < after) { // need added trailing zeros
22497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // [thisafter can be negative]
22507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newmant = extend(num.mant, (num.mant.length + after) - thisafter);
22517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.mant = newmant;
22527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.exp = num.exp - ((after - thisafter)); // adjust exponent
22537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (num.exp < MinExp)
22547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp);
22557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break setafter;
22567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // We have too many digits after the decimal point; this could
22587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // cause a carry, which could change the mantissa...
22597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // Watch out for implied leading zeros in PLAIN case
22607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                chop = thisafter - after; // digits to lop [is >0]
22617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (chop > num.mant.length) { // all digits go, no chance of carry
22627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // carry on with zero
22637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.mant = ZERO.mant;
22647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.ind = iszero;
22657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    num.exp = 0;
22667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue setafter; // recheck: we may need trailing zeros
22677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // we have a digit to inspect from existing mantissa
22697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // round the number as required
22707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                need = num.mant.length - chop; // digits to end up with [may be 0]
22717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                oldexp = num.exp; // save old exponent
22727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                num.round(need, exround);
22737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // if the exponent grew by more than the digits we chopped, then
22747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // we must have had a carry, so will need to recheck the layout
22757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((num.exp - oldexp) == chop)
22767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break setafter; // number did not have carry
22777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // mantissa got extended .. so go around and check again
22787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* setafter */
22807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        a = num.layout(); // lay out, with exponent if required, etc.
22827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Here we have laid-out number in 'a' */
22847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // now apply 'before' and 'explaces' as needed
22857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (before > 0) {
22867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // look for '.' or 'E'
22877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
22887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $11 = a.length;
22897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                p = 0;
22907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                p: for (; $11 > 0; $11--, p++) {
22917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (a[p] == '.')
22927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break p;
22937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (a[p] == 'E')
22947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break p;
22957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* p */
22977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // p is now offset of '.', 'E', or character after end of array
22987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // that is, the current length of before part
22997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (p > before)
23007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                badarg("format", 1, java.lang.String.valueOf(before)); // won't fit
23017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (p < before) { // need leading blanks
23027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newa = new char[(a.length + before) - p];
23037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
23047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $12 = before - p;
23057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = 0;
23067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $12 > 0; $12--, i++) {
23077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newa[i] = ' ';
23087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
23097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
23102d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                java.lang.System.arraycopy(a, 0, newa, i, a.length);
23117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                a = newa;
23127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
23137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [if p=before then it's just the right length]
23147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
23157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (explaces > 0) {
23177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // look for 'E' [cannot be at offset 0]
23187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
23197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $13 = a.length - 1;
23207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                p = a.length - 1;
23217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                p: for (; $13 > 0; $13--, p--) {
23227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (a[p] == 'E')
23237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break p;
23247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
23257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* p */
23267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // p is now offset of 'E', or 0
23277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (p == 0) { // no E part; add trailing blanks
23287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newa = new char[(a.length + explaces) + 2];
23292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                java.lang.System.arraycopy(a, 0, newa, 0, a.length);
23307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
23317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int $14 = explaces + 2;
23327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = a.length;
23337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (; $14 > 0; $14--, i++) {
23347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newa[i] = ' ';
23357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
23367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
23377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                a = newa;
23387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {/* found E */// may need to insert zeros
23397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                places = (a.length - p) - 2; // number so far
23407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (places > explaces)
23417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    badarg("format", 3, java.lang.String.valueOf(explaces));
23427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (places < explaces) { // need to insert zeros
23437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newa = new char[(a.length + explaces) - places];
23442d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                    java.lang.System.arraycopy(a, 0, newa, 0, p + 2); // through E
23457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                            // and sign
23467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    {
23477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        int $15 = explaces - places;
23487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        i = p + 2;
23497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        for (; $15 > 0; $15--, i++) {
23507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            newa[i] = '0';
23517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
23527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }/* i */
23532d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                    java.lang.System.arraycopy(a, p + 2, newa, i, places); // remainder
23547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                                 // of
23557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                                                                 // exponent
23567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    a = newa;
23577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
23587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // [if places=explaces then it's just the right length]
23597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
23607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
23617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new java.lang.String(a);
23627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
23637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
23657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the hashcode for this <code>BigDecimal</code>. This hashcode is suitable for use by the <code>
23667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * java.util.Hashtable</code> class.
23677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
23687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note that two <code>BigDecimal</code> objects are only guaranteed to produce the same hashcode if they are
23697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * exactly equal (that is, the <code>String</code> representations of the <code>BigDecimal</code> numbers are
23707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * identical -- they have the same characters in the same sequence).
23712d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
23727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> that is the hashcode for <code>this</code>.
23737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
23747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
23757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23762d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
23777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int hashCode() {
23787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Maybe calculate ourselves, later. If so, note that there can be
23797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // more than one internal representation for a given toString() result.
23807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this.toString().hashCode();
23817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
23827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
23847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
23857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for an <code>int</code>
23867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be
23877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact}
23887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * method.
23892d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
23907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> converted from <code>this</code>, truncated and decapitated if necessary.
23917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
23927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
23937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23942d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
23957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int intValue() {
23967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return toBigInteger().intValue();
23977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
23987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
24007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
24017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part or is out of the possible range for an <code>int</code> (32-bit signed integer) result then an
24027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>ArithmeticException</code> is thrown.
24032d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
24047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> equal in value to <code>this</code>.
24057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in an <code>int</code>.
24067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
24077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
24087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int intValueExact() {
24107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int lodigit;
24117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int useexp = 0;
24127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int result;
24137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
24147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int topdig = 0;
24157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // This does not use longValueExact() as the latter can be much
24167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // slower.
24177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // intcheck (from pow) relies on this to check decimal part
24187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ind == iszero)
24197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 0; // easy, and quite common
24207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test and drop any trailing decimal part */
24217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lodigit = mant.length - 1;
24227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp < 0) {
24237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            lodigit = lodigit + exp; // reduces by -(-exp)
24247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* all decimal places must be 0 */
24257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((!(allzero(mant, lodigit + 1))))
24267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
24277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lodigit < 0)
24287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return 0; // -1<this<1
24297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            useexp = 0;
24307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* >=0 */
24317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((exp + lodigit) > 9) // early exit
24327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
24337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            useexp = exp;
24347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
24357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* convert the mantissa to binary, inline for speed */
24367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        result = 0;
24377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
24387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $16 = lodigit + useexp;
24397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 0;
24407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; i <= $16; i++) {
24417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                result = result * 10;
24427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (i <= lodigit)
24437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    result = result + mant[i];
24447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
24457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
24467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Now, if the risky length, check for overflow */
24487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((lodigit + useexp) == 9) {
24497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // note we cannot just test for -ve result, as overflow can move a
24507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // zero into the top bit [consider 5555555555]
24517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            topdig = result / 1000000000; // get top digit, preserving sign
24527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (topdig != mant[0]) { // digit must match and be positive
24537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // except in the special case ...
24547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (result == java.lang.Integer.MIN_VALUE) // looks like the special
24557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (ind == isneg) // really was negative
24567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (mant[0] == 2)
24577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return result; // really had top digit 2
24587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
24597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
24607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
24617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Looks good */
24637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ind == ispos)
24647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return result;
24657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return -result;
24667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
24677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
24697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
24707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for a <code>long</code>
24717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be
24727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact}
24737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * method.
24742d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
24757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>long</code> converted from <code>this</code>, truncated and decapitated if necessary.
24767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
24777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
24787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24792d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
24807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public long longValue() {
24817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return toBigInteger().longValue();
24827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
24837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
24857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
24867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part or is out of the possible range for a <code>long</code> (64-bit signed integer) result then an
24877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>ArithmeticException</code> is thrown.
24882d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
24897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>long</code> equal in value to <code>this</code>.
24907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>long</code>.
24917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
24927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
24937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
24947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public long longValueExact() {
24957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int lodigit;
24967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int cstart = 0;
24977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int useexp = 0;
24987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long result;
24997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
25007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long topdig = 0;
25017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Identical to intValueExact except for result=long, and exp>=20 test
25027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ind == 0)
25037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 0; // easy, and quite common
25047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lodigit = mant.length - 1; // last included digit
25057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp < 0) {
25067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            lodigit = lodigit + exp; // -(-exp)
25077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* all decimal places must be 0 */
25087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lodigit < 0)
25097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cstart = 0;
25107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else
25117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cstart = lodigit + 1;
25127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((!(allzero(mant, cstart))))
25137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
25147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lodigit < 0)
25157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return 0; // -1<this<1
25167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            useexp = 0;
25177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* >=0 */
25187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((exp + mant.length) > 18) // early exit
25197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
25207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            useexp = exp;
25217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
25227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* convert the mantissa to binary, inline for speed */
25247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // note that we could safely use the 'test for wrap to negative'
25257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // algorithm here, but instead we parallel the intValueExact
25267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // algorithm for ease of checking and maintenance.
25272d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        result = 0;
25287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
25297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $17 = lodigit + useexp;
25307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 0;
25317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; i <= $17; i++) {
25327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                result = result * 10;
25337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (i <= lodigit)
25347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    result = result + mant[i];
25357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
25367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
25377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Now, if the risky length, check for overflow */
25397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((lodigit + useexp) == 18) {
25407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            topdig = result / 1000000000000000000L; // get top digit, preserving sign
25417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (topdig != mant[0]) { // digit must match and be positive
25427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // except in the special case ...
25437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (result == java.lang.Long.MIN_VALUE) // looks like the special
25447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (ind == isneg) // really was negative
25457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (mant[0] == 9)
25467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return result; // really had top digit 9
25477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
25487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
25497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
25507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Looks good */
25527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ind == ispos)
25537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return result;
25547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return -result;
25557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
25567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
25587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the left by a specified number of
25597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
25607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * if <code>n</code> is 0 or positive, the number returned is given by:
25617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
25627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code> this.multiply(TEN.pow(new BigDecimal(-n))) </code>
25637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
25647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointRight(-n)
25657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>.
25662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
25677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param n The <code>int</code> specifying the number of places to move the decimal point leftwards.
25687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
25697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         places to the left.
25707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
25717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
25727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal movePointLeft(int n) {
25747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
25757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // very little point in optimizing for shift of 0
25767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = clone(this);
25777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.exp = res.exp - n;
25787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(plainMC, false); // finish sets form and checks exponent
25797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
25807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
25827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the right by a specified number of
25837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
25847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * if <code>n</code> is 0 or positive, the number returned is given by:
25857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
25867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code> this.multiply(TEN.pow(new BigDecimal(n))) </code>
25877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
25887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointLeft(-n)
25897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </code>.
25902d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
25917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param n The <code>int</code> specifying the number of places to move the decimal point rightwards.
25927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
25937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         places to the right.
25947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
25957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
25967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
25977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal movePointRight(int n) {
25987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
25997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = clone(this);
26007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.exp = res.exp + n;
26017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(plainMC, false);
26027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
26037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
26057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the scale of this <code>BigDecimal</code>. Returns a non-negative <code>int</code> which is the scale of
26067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the number. The scale is the number of digits in the decimal part of the number if the number were formatted
26077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * without exponential notation.
26082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
26097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> whose value is the scale of this <code>BigDecimal</code>.
26107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
26117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
26127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int scale() {
26147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp >= 0)
26157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 0; // scale can never be negative
26167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return -exp;
26177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
26187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
26207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> with a given scale.
26217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
26237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
26247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
26267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * trailing digits will be removed, and in this case an <code>ArithmeticException</code> is thrown if any discarded
26277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * digits are non-zero.
26287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is <code>
26307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * MathContext.ROUND_UNNECESSARY</code>.
26312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
26327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
26337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A plain <code>BigDecimal</code> with the given scale.
26347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>scale</code> is negative.
26357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if reducing scale would discard non-zero digits.
26367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
26377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
26387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal setScale(int scale) {
26407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return setScale(scale, ROUND_UNNECESSARY);
26417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
26427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
26447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a plain <code>BigDecimal</code> with a given scale.
26457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
26477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
26487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
26507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the
26517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * remaining digits are affected by a carry. In this case, an <code>IllegalArgumentException</code> is thrown if
26527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>round</code> is not a valid rounding mode.
26537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
26547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, an <code>ArithmeticException</code> is
26557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * thrown if any discarded digits are non-zero.
26562d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
26577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
26587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
26597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A plain <code>BigDecimal</code> with the given scale.
26607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
26617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>scale</code> is negative.
26627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, and reducing scale would discard
26637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *             non-zero digits.
26647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
26657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
26667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
26677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public com.ibm.icu.math.BigDecimal setScale(int scale, int round) {
26687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ourscale;
26697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
26707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int padding = 0;
26717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newlen = 0;
26727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // at present this naughtily only checks the round value if it is
26737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // needed (used), for speed
26747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ourscale = this.scale();
26757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ourscale == scale) // already correct scale
26767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form
26777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return this;
26787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = clone(this); // need copy
26797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (ourscale <= scale) { // simply zero-padding/changing form
26807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // if ourscale is 0 we may have lots of 0s to add
26817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (ourscale == 0)
26827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                padding = res.exp + scale;
26837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else
26847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                padding = scale - ourscale;
26857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.mant = extend(res.mant, res.mant.length + padding);
26867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.exp = -scale; // as requested
26877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* ourscale>scale: shortening, probably */
26887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (scale < 0)
26897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
26907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [round() will raise exception if invalid round]
26917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK]
26927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res = res.round(newlen, round); // round to required length
26937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // This could have shifted left if round (say) 0.9->1[.0]
26947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Repair if so by adding a zero and reducing exponent
26957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (res.exp != -scale) {
26967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res.mant = extend(res.mant, res.mant.length + 1);
26977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res.exp = res.exp - 1;
26987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
26997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
27007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition
27017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res;
27027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
27037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
27057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>short</code>. If the <code>BigDecimal</code> has a non-zero
27067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * decimal part or is out of the possible range for a <code>short</code> (16-bit signed integer) result then an
27077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>ArithmeticException</code> is thrown.
27082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
27097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A <code>short</code> equal in value to <code>this</code>.
27107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>short</code>.
27117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
27127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
27137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public short shortValueExact() {
27157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int num;
27167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        num = this.intValueExact(); // will check decimal part too
27177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((num > 32767) | (num < (-32768)))
27187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
27197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return (short) num;
27207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
27217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
27237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the sign of this <code>BigDecimal</code>, as an <code>int</code>. This returns the <i>signum</i> function
27247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * value that represents the sign of this <code>BigDecimal</code>. That is, -1 if the <code>BigDecimal</code> is
27257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * negative, 0 if it is numerically equal to zero, or 1 if it is positive.
27262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
27277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return An <code>int</code> which is -1 if the <code>BigDecimal</code> is negative, 0 if it is numerically equal
27287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         to zero, or 1 if it is positive.
27297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
27307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
27317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int signum() {
27332d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        return this.ind; // [note this assumes values for ind.]
27347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
27357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
27377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>java.math.BigDecimal</code>.
27387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
27397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This is an exact conversion; the result is the same as if the <code>BigDecimal</code> were formatted as a plain
27407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * number without any rounding or exponent and then the <code>java.math.BigDecimal(java.lang.String)</code>
27417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * constructor were used to construct the result.
27427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
27437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <i>(Note: this method is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class. It
27447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * would not be present in a <code>java.math</code> version.)</i>
27452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
27467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>java.math.BigDecimal</code> equal in value to this <code>BigDecimal</code>.
27477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
27487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
27497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.math.BigDecimal toBigDecimal() {
27517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new java.math.BigDecimal(this.unscaledValue(), this.scale());
27527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
27537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
27557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
27567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
27577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use
27587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #toBigIntegerExact()}.
27592d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
27607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
27617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
27627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
27637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.math.BigInteger toBigInteger() {
27657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res = null;
27667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newlen = 0;
27677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newmant[] = null;
27687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/* select */
27697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN))
27707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = this; // can layout simply
27717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else if (exp >= 0) {
27727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = clone(this); // safe copy
27737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
27747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
27757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                { // exp<0; scale to be truncated
27767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // we could use divideInteger, but we may as well be quicker
27777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (-this.exp >= this.mant.length)
27787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        res = ZERO; // all blows away
27797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else {
27807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        res = clone(this); // safe copy
27817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newlen = res.mant.length + res.exp;
27827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newmant = new byte[newlen]; // [shorter]
27832d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                        java.lang.System.arraycopy(res.mant, 0, newmant, 0,
27847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                newlen);
27857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        res.mant = newmant;
27867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
27877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        res.exp = 0;
27887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
27897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
27907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
27917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
27927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new BigInteger(new java.lang.String(res.layout()));
27937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
27947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
27957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
27967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
27977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
27987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * An exception is thrown if the decimal part (if any) is non-zero.
27992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
28017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part.
28027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
28037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
28047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.math.BigInteger toBigIntegerExact() {
28067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test any trailing decimal part */
28077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp < 0) { // possible decimal part
28087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* all decimal places must be 0; note exp<0 */
28097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((!(allzero(mant, mant.length + exp))))
28107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
28117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
28127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return toBigInteger();
28137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
28147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
28167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the <code>BigDecimal</code> as a character array. The result of this method is the same as using the
28177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * sequence <code>toString().toCharArray()</code>, but avoids creating the intermediate <code>String</code> and
28187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>char[]</code> objects.
28192d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>char[]</code> array corresponding to this <code>BigDecimal</code>.
28217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
28227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
28237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public char[] toCharArray() {
28257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return layout();
28267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
28277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
28297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the <code>BigDecimal</code> as a <code>String</code>. This returns a <code>String</code> that exactly
28307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * represents this <code>BigDecimal</code>, as defined in the decimal documentation (see {@link BigDecimal class
28317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * header}).
28327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
28337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * By definition, using the {@link #BigDecimal(String)} constructor on the result <code>String</code> will create a
28347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>BigDecimal</code> that is exactly equal to the original <code>BigDecimal</code>.
28352d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>String</code> exactly corresponding to this <code>BigDecimal</code>.
28377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #format(int, int)
28387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #format(int, int, int, int, int, int)
28397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #toCharArray()
28407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
28417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
28427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Override
28447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.lang.String toString() {
28457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new java.lang.String(layout());
28467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
28477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
28497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the number as a <code>BigInteger</code> after removing the scale. That is, the number is expressed as a
28507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is
28517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * then converted to a <code>BigInteger</code>.
28522d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>java.math.BigInteger</code> equal in value to this <code>BigDecimal</code> multiplied by ten to
28547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         the power of <code>this.scale()</code>.
28557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
28567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
28577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public java.math.BigInteger unscaledValue() {
28597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res = null;
28607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp >= 0)
28617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res = this;
28627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else {
28637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res = clone(this); // safe copy
28647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.exp = 0; // drop scale
28657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
28667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.toBigInteger();
28677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
28687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
28707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Translates a <code>double</code> to a <code>BigDecimal</code>.
28717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
28727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a <code>BigDecimal</code> which is the decimal representation of the 64-bit signed binary floating point
28737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * parameter. If the parameter is infinite, or is not a number (NaN), a <code>NumberFormatException</code> is
28747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * thrown.
28757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
28767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The number is constructed as though <code>num</code> had been converted to a <code>String</code> using the <code>
28777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Double.toString()</code> method and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
28787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This is typically not an exact conversion.
28792d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param dub The <code>double</code> to be translated.
28817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>BigDecimal</code> equal in value to <code>dub</code>.
28827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException if the parameter is infinite or not a number.
28837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
28847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
28857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static com.ibm.icu.math.BigDecimal valueOf(double dub) {
28877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Reminder: a zero double returns '0.0', so we cannot fastpath to
28887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // use the constant ZERO. This might be important enough to justify
28897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // a factory approach, a cache, or a few private constants, later.
28907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());
28917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
28927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
28937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
28947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Translates a <code>long</code> to a <code>BigDecimal</code>. That is, returns a plain <code>BigDecimal</code>
28957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * whose value is equal to the given <code>long</code>.
28962d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
28977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param lint The <code>long</code> to be translated.
28987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
28997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
29007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
29017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
29037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return valueOf(lint, 0);
29047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
29057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
29077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Translates a <code>long</code> to a <code>BigDecimal</code> with a given scale. That is, returns a plain <code>
29087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * BigDecimal</code> whose unscaled value is equal to the given <code>long</code>, adjusted by the second parameter,
29097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>scale</code>.
29107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
29117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The result is given by:
29127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
29137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code> (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) </code>
29147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
29157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * A <code>NumberFormatException</code> is thrown if <code>scale</code> is negative.
29162d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
29177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param lint The <code>long</code> to be translated.
29187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param scale The <code>int</code> scale to be applied.
29197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
29207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws NumberFormatException if the scale is negative.
29217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.0
29227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
29237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) {
29257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res = null;
29267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/* select */
29277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lint == 0)
29287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = ZERO;
29297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else if (lint == 1)
29307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = ONE;
29317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else if (lint == 10)
29327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = TEN;
29337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
29347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res = new com.ibm.icu.math.BigDecimal(lint);
29357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
29367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
29377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (scale == 0)
29387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return res;
29397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (scale < 0)
29407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
29417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = clone(res); // safe copy [do not mutate]
29427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.exp = -scale; // exponent is -scale
29437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res;
29447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
29457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
29477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* Private methods */
29487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* ---------------------------------------------------------------- */
29497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
29517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array).
29527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>The mantissa will either already have been rounded (following an operation) or will be of length appropriate
29537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (in the case of construction from an int, for example). <p>We must not alter the mantissa, here. <p>'form'
29547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure
29557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * numeric. </sgml>
29567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
29577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private char[] layout() {
29597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char cmant[];
29607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
29617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder sb = null;
29627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int euse = 0;
29637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int sig = 0;
29647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char csign = 0;
29657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        char rec[] = null;
29667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int needsign;
29677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mag;
29687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int len = 0;
29697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cmant = new char[mant.length]; // copy byte[] to a char[]
29707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
29717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $18 = mant.length;
29727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 0;
29737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; $18 > 0; $18--, i++) {
29742d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                cmant[i] = (char) (mant[i] + (('0')));
29757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
29767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
29777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
29787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */
29797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999
29807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (ind == isneg)
29817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                sb.append('-');
29827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            euse = (exp + cmant.length) - 1; // exponent to use
29837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /* setup sig=significant digits and copy to result */
29847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default]
29857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                sb.append(cmant[0]); // significant character
29867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (cmant.length > 1) // have decimal part
29877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    sb.append('.').append(cmant, 1, cmant.length - 1);
29887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
29897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                do {
29907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    sig = euse % 3; // common
29917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (sig < 0)
29927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        sig = 3 + sig; // negative exponent
29937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    euse = euse - sig;
29947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    sig++;
29957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (sig >= cmant.length) { // zero padding may be needed
29967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        sb.append(cmant, 0, cmant.length);
29977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        {
29987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            int $19 = sig - cmant.length;
29997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            for (; $19 > 0; $19--) {
30007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                sb.append('0');
30017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
30027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
30037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } else { // decimal point needed
30047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig);
30057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
30067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } while (false);
30077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* engineering */
30087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (euse != 0) {
30097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (euse < 0) {
30107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    csign = '-';
30117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    euse = -euse;
30127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else
30137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    csign = '+';
30147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                sb.append('E').append(csign).append(euse);
30157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
30167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec = new char[sb.length()];
30177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int srcEnd = sb.length();
30187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (0 != srcEnd) {
30197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                sb.getChars(0, srcEnd, rec, 0);
30207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
30217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rec;
30227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
30237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Here for non-exponential (plain) notation */
30257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp == 0) {/* easy */
30267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (ind >= 0)
30277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return cmant; // non-negative integer
30287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec = new char[cmant.length + 1];
30297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec[0] = '-';
30302d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(cmant, 0, rec, 1, cmant.length);
30317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rec;
30327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
30337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Need a '.' and/or some zeros */
30357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1
30367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
30387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * MAG is the position of the point in the mantissa (index of the character it follows)
30397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
30407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mag = exp + cmant.length;
30417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (mag < 1) {/* 0.00xxxx form */
30437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length
30447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec = new char[len];
30457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (needsign != 0)
30467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rec[0] = '-';
30477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec[needsign] = '0';
30487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec[needsign + 1] = '.';
30497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
30507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $20 = -mag;
30517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                i = needsign + 2;
30527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (; $20 > 0; $20--, i++) { // maybe none
30537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    rec[i] = '0';
30547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
30557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* i */
30562d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(cmant, 0, rec, (needsign + 2) - mag,
30577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    cmant.length);
30587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rec;
30597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
30607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (mag > cmant.length) {/* xxxx0000 form */
30627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            len = needsign + mag;
30637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec = new char[len];
30647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (needsign != 0)
30657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rec[0] = '-';
30662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(cmant, 0, rec, needsign, cmant.length);
30677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
30687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int $21 = mag - cmant.length;
30697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                i = needsign + cmant.length;
30707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (; $21 > 0; $21--, i++) { // never 0
30717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    rec[i] = '0';
30727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
30737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* i */
30747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return rec;
30757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
30767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* decimal point is in the middle of the mantissa */
30787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        len = (needsign + 1) + cmant.length;
30797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        rec = new char[len];
30807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (needsign != 0)
30817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rec[0] = '-';
30822d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        java.lang.System.arraycopy(cmant, 0, rec, needsign, mag);
30837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        rec[needsign + mag] = '.';
30842d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        java.lang.System.arraycopy(cmant, mag, rec, (needsign + mag) + 1,
30857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cmant.length - mag);
30867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return rec;
30877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
30887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
30907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Checks a BigDecimal argument to ensure it's a true integer in a given range. <p>If OK, returns it as an
30917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * int. </sgml>
30927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
30937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // [currently only used by pow]
30947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int intcheck(int min, int max) {
30957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i;
30967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        i = this.intValueExact(); // [checks for non-0 decimal part]
30977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Use same message as though intValueExact failed due to size
30987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((i < min) | (i > max))
30997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i);
31007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return i;
31017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
31027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* <sgml> Carry out division operations. </sgml> */
31047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
31057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is
31067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * explicit scale iff code='D' or 'I' (-1 if none).
31072d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
31087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity):
31092d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
31107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1)
31117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for
31127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave
31137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -)
31147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If
31157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor
31167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do
31177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if
31187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1
31192d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
31207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * For extended commentary, see DMSRCN.
31217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
31227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs,
31247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            com.ibm.icu.math.MathContext set, int scale) {
31257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal lhs;
31267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int reqdig;
31277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newexp;
31287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal res;
31297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newlen;
31307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte var1[];
31317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int var1len;
31327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte var2[];
31337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int var2len;
31347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int b2b;
31357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int have;
31367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int thisdigit = 0;
31377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
31387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte v2 = 0;
31397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ba = 0;
31407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mult = 0;
31417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int start = 0;
31427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int padding = 0;
31437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int d = 0;
31447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newvar1[] = null;
31457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte lasthave = 0;
31467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int actdig = 0;
31477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newmant[] = null;
31487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.lostDigits)
31507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            checkdigits(rhs, set.digits);
31517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        lhs = this; // name for clarity
31527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // [note we must have checked lostDigits before the following checks]
31547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rhs.ind == 0)
31557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
31567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s]
31577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
31587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return ZERO;
31597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (scale == (-1))
31607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return lhs;
31617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return lhs.setScale(scale);
31627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
31637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Prepare numbers according to BigDecimal rules */
31657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        reqdig = set.digits; // local copy (heavily used)
31667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reqdig > 0) {
31677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lhs.mant.length > reqdig)
31687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                lhs = clone(lhs).round(set);
31697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rhs.mant.length > reqdig)
31707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rhs = clone(rhs).round(set);
31717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* scaled divide */
31727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (scale == (-1))
31737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                scale = lhs.scale();
31747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // set reqdig to be at least large enough for the computation
31757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            reqdig = lhs.mant.length; // base length
31767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // next line handles both positive lhs.exp and also scale mismatch
31777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (scale != -lhs.exp)
31787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                reqdig = (reqdig + scale) + lhs.exp;
31797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect
31807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (reqdig < lhs.mant.length)
31817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                reqdig = lhs.mant.length; // clamp
31827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (reqdig < rhs.mant.length)
31837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                reqdig = rhs.mant.length; // ..
31847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
31857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* precalculate exponent */
31877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length;
31887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* If new exponent -ve, then some quick exits are possible */
31897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (newexp < 0)
31907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (code != 'D') {
31917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (code == 'I')
31927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return ZERO; // easy - no integer part
31937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* Must be 'R'; remainder is [finished clone of] input value */
31947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return clone(lhs).finish(set, false);
31957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
31967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
31977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* We need slow division */
31987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
31997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I)
32007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.exp = newexp; // initial exponent (for D/I)
32017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        res.mant = new byte[reqdig + 1]; // where build the result
32027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
32037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Now [virtually pad the mantissae with trailing zeros */
32047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Also copy the LHS, which will be our working array
32057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newlen = (reqdig + reqdig) + 1;
32067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array
32077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        var1len = newlen; // [remaining digits are 0]
32087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
32097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        var2 = rhs.mant;
32107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        var2len = newlen;
32117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
32127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Calculate first two digits of rhs (var2), +1 for later estimations */
32137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        b2b = (var2[0] * 10) + 1;
32147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (var2.length > 1)
32157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            b2b = b2b + var2[1];
32167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
32177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* start the long-division loops */
32187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        have = 0;
32197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
32207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            outer: for (;;) {
32217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                thisdigit = 0;
32227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* find the next digit */
32237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
32247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    inner: for (;;) {
32257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (var1len < var2len)
32267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            break inner; // V1 too low
32277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (var1len == var2len) { // compare needed
32287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            {
32297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                compare: do { // comparison
32307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    {
32317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        int $22 = var1len;
32327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i = 0;
32337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        for (; $22 > 0; $22--, i++) {
32347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            // var1len is always <= var1.length
32357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            if (i < var2.length)
32367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                v2 = var2[i];
32377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            else
32387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                v2 = (byte) 0;
32397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            if (var1[i] < v2)
32407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                break inner; // V1 too low
32417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                            if (var1[i] > v2)
32427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                break compare; // OK to subtract
32437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        }
32447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    }/* i */
32457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    /*
32467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                     * reach here if lhs and rhs are identical; subtraction will increase digit by one,
32477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                     * and the residue will be 0 so we are done; leave the loop with residue set to 0
32487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                     * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked)
32497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                     */
32507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    thisdigit++;
32517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    res.mant[have] = (byte) thisdigit;
32527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    have++;
32537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    var1[0] = (byte) 0; // residue to 0 [this is all we'll test]
32547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    // var1len=1 -- [optimized out]
32557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    break outer;
32567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                } while (false);
32577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }/* compare */
32587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            /* prepare for subtraction. Estimate BA (lengths the same) */
32592d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                            ba = var1[0]; // use only first digit
32607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } // lengths the same
32617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        else {/* lhs longer than rhs */
32627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            /* use first two digits for estimate */
32637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ba = var1[0] * 10;
32647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (var1len > 1)
32657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                ba = ba + var1[1];
32667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
32677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        /* subtraction needed; V1>=V2 */
32687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        mult = (ba * 10) / b2b;
32697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (mult == 0)
32707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            mult = 1;
32717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        thisdigit = thisdigit + mult;
32727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // subtract; var1 reusable
32737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true);
32747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (var1[0] != 0)
32757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            continue inner; // maybe another subtract needed
32767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        /*
32777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than
32787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         * V2)
32797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         */
32807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        {
32817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            int $23 = var1len - 2;
32827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            start = 0;
32837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            start: for (; start <= $23; start++) {
32847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                if (var1[start] != 0)
32857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    break start;
32867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                var1len--;
32877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
32887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }/* start */
32897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (start == 0)
32907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            continue inner;
32917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // shift left
32922d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                        java.lang.System.arraycopy(var1, start, var1, 0, var1len);
32937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
32947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* inner */
32957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
32967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* We have the next digit */
32977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((have != 0) | (thisdigit != 0)) { // put the digit we got
32987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.mant[have] = (byte) thisdigit;
32997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    have++;
33007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (have == (reqdig + 1))
33017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break outer; // we have all we need
33027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (var1[0] == 0)
33037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break outer; // residue now 0
33047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
33057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* can leave now if a scaled divide and exponent is small enough */
33067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (scale >= 0)
33077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (-res.exp > scale)
33087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break outer;
33097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* can leave now if not Divide and no integer part left */
33107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (code != 'D')
33117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (res.exp <= 0)
33127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break outer;
33137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res.exp = res.exp - 1; // reduce the exponent
33147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /*
33157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit
33167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 */
33177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                var2len--;
33187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
33197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* outer */
33207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* here when we have finished dividing, for some reason */
33227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // have is the number of digits we collected in res.mant
33237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (have == 0)
33247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            have = 1; // res.mant[0] is 0; we always want a digit
33257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */
33277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((have + res.exp) > reqdig)
33287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Integer overflow");
33297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (code == 'R') {
33317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                do {
33327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    /* We were doing Remainder -- return the residue */
33337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (res.mant[0] == 0) // no integer part was found
33347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return clone(lhs).finish(set, false); // .. so return lhs, canonical
33357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (var1[0] == 0)
33367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return ZERO; // simple 0 residue
33377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.ind = lhs.ind; // sign is always as LHS
33387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    /*
33397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     * Calculate the exponent by subtracting the number of padding zeros we added and adding the
33407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     * original exponent
33417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     */
33427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    padding = ((reqdig + reqdig) + 1) - lhs.mant.length;
33437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = (res.exp - padding) + lhs.exp;
33447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    /*
33467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be
33477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     */
33487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    d = var1len;
33497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    {
33507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        i = d - 1;
33517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        i: for (; i >= 1; i--) {
33527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (!((res.exp < lhs.exp) & (res.exp < rhs.exp)))
33537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                break;
33547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (var1[i] != 0)
33557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                break i;
33567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            d--;
33577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            res.exp = res.exp + 1;
33587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
33597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }/* i */
33607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (d < var1.length) {/* need to reduce */
33617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newvar1 = new byte[d];
33622d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                        java.lang.System.arraycopy(var1, 0, newvar1, 0, d); // shorten
33637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        var1 = newvar1;
33647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
33657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.mant = var1;
33667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return res.finish(set, false);
33677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } while (false);
33687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }/* remainder */
33697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
33707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else {/* 'D' -- no overflow check needed */
33727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If there was a residue then bump the final digit (iff 0 or 5)
33737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
33747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ROUND_UNNECESSARY checks (etc.) later.
33757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [if we finished early, the residue will be 0]
33767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (var1[0] != 0) { // residue not 0
33777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                lasthave = res.mant[have - 1];
33787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (((lasthave % 5)) == 0)
33797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.mant[have - 1] = (byte) (lasthave + 1);
33807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
33817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
33827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
33837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Here for Divide or Integer Divide */
33847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // handle scaled results first ['I' always scale 0, optional for 'D']
33857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (scale >= 0) {
33867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {
33877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // say 'scale have res.exp len' scale have res.exp res.mant.length
33887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (have != res.mant.length)
33897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // already padded with 0's, so just adjust exponent
33907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = res.exp - ((res.mant.length - have));
33917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // calculate number of digits we really want [may be 0]
33927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                actdig = res.mant.length - (-res.exp - scale);
33937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                res.round(actdig, set.roundingMode); // round to desired length
33947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // This could have shifted left if round (say) 0.9->1[.0]
33957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // Repair if so by adding a zero and reducing exponent
33967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (res.exp != -scale) {
33977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.mant = extend(res.mant, res.mant.length + 1);
33987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    res.exp = res.exp - 1;
33997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
34007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return res.finish(set, true); // [strip if not PLAIN]
34017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
34027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* scaled */
34037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // reach here only if a non-scaled
34057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (have == res.mant.length) { // got digits+1 digits
34067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.round(set);
34077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            have = reqdig;
34087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* have<=reqdig */
34097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (res.mant[0] == 0)
34107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return ZERO; // fastpath
34117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // make the mantissa truly just 'have' long
34127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // [we could let finish do this, during strip, if we adjusted
34137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // the exponent; however, truncation avoids the strip loop]
34147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            newmant = new byte[have]; // shorten
34152d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(res.mant, 0, newmant, 0, have);
34167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            res.mant = newmant;
34177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
34187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return res.finish(set, true);
34197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
34207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* <sgml> Report a conversion exception. </sgml> */
34227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void bad(char s[]) {
34247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s));
34257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
34267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
34287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Report a bad argument to a method. </sgml> Arg1 is method name Arg2 is argument position Arg3 is what was
34297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * found
34307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
34317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void badarg(java.lang.String name, int pos, java.lang.String value) {
34337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " "
34347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                + value);
34357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
34367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
34387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Extend byte array to given length, padding with 0s. If no extension is required then return the same
34397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * array. </sgml>
34402d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
34417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Arg1 is the source byte array Arg2 is the new length (longer)
34427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
34437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte[] extend(byte inarr[], int newlen) {
34457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newarr[];
34467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (inarr.length == newlen)
34477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return inarr;
34487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newarr = new byte[newlen];
34492d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        java.lang.System.arraycopy(inarr, 0, newarr, 0, inarr.length);
34507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 0 padding is carried out by the JVM on allocation initialization
34517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return newarr;
34527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
34537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
34557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Add or subtract two >=0 integers in byte arrays <p>This routine performs the calculation: <pre> C=A+(BM)
34567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </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
34577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * non-negative.
34582d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
34597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B,
34607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * or 1 longer than that (if a carry occurred).
34612d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
34627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * A is not altered unless Arg6 is 1. B is never altered.
34632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
34647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 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
34657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 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)
34662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
34677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance
34687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * degradation.
34697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
34707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
34717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1997.10.05 -- changed to byte arrays (from char arrays)
34727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1998.07.01 -- changed to allow destructive reuse of LHS
34737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1998.07.01 -- changed to allow virtual lengths for the arrays
34747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1998.12.29 -- use lookaside for digit/carry calculation
34757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1999.08.07 -- avoid multiply when mult=1, and make db an int
34767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // 1999.12.22 -- special case m=-1, also drop 0 special case
34777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) {
34787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int alength;
34797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int blength;
34807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int ap;
34817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int bp;
34827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int maxarr;
34837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte reb[];
34847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean quickm;
34857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int digit;
34867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int op = 0;
34877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dp90 = 0;
34887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newarr[];
34897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
34907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
34917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We'll usually be right if we assume no carry
34927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        alength = a.length; // physical lengths
34937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        blength = b.length; // ..
34947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ap = avlen - 1; // -> final (rightmost) digit
34957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bp = bvlen - 1; // ..
34967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        maxarr = bp;
34977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (maxarr < ap)
34987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            maxarr = ap;
34992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        reb = null; // result byte array
35007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reuse)
35017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((maxarr + 1) == alength)
35027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                reb = a; // OK to reuse A
35037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reb == null)
35047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            reb = new byte[maxarr + 1]; // need new array
35057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        quickm = false; // 1 if no multiply needed
35077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (m == 1)
35087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            quickm = true; // most common
35097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else if (m == (-1))
35107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            quickm = true; // also common
35117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        digit = 0; // digit, with carry or borrow
35137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
35147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            op = maxarr;
35157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            op: for (; op >= 0; op--) {
35167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (ap >= 0) {
35177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (ap < alength)
35187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        digit = digit + a[ap]; // within A
35197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ap--;
35207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
35217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (bp >= 0) {
35227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (bp < blength) { // within B
35237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (quickm) {
35247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (m > 0)
35257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                digit = digit + b[bp]; // most common
35267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            else
35277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                digit = digit - b[bp]; // also common
35287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } else
35297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            digit = digit + (b[bp] * m);
35307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
35317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bp--;
35327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
35337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* result so far (digit) could be -90 through 99 */
35347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (digit < 10)
35357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (digit >= 0) {
35367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        do { // 0-9
35377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            reb[op] = (byte) digit;
35387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            digit = 0; // no carry
35397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            continue op;
35407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } while (false);
35417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }/* quick */
35427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                dp90 = digit + 90;
35437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                reb[op] = bytedig[dp90]; // this digit
35447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                digit = bytecar[dp90]; // carry or borrow
35457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
35467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* op */
35477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (digit == 0)
35497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return reb; // no carry
35507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // following line will become an Assert, later
35517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // if digit<0 then signal ArithmeticException("internal.error ["digit"]")
35527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* We have carry -- need to make space for the extra digit */
35542d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        newarr = null;
35557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (reuse)
35567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((maxarr + 2) == a.length)
35577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newarr = a; // OK to reuse A
35587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (newarr == null)
35597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            newarr = new byte[maxarr + 2];
35607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        newarr[0] = (byte) digit; // the carried digit ..
35617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // .. and all the rest [use local loop for short numbers]
35627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (maxarr < 10) {
35637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $24 = maxarr + 1;
35647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 0;
35657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; $24 > 0; $24--, i++) {
35667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newarr[i + 1] = reb[i];
35677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
35687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
35697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
35702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(reb, 0, newarr, 1, maxarr + 1);
35717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return newarr;
35727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
35737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
35757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Initializer for digit array properties (lookaside). </sgml> Returns the digit array, and initializes the
35767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * carry array.
35777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
35787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
35797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final byte[] diginit() {
35807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte work[];
35817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int op = 0;
35827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int digit = 0;
35837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        work = new byte[(90 + 99) + 1];
35847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
35857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            op = 0;
35867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            op: for (; op <= (90 + 99); op++) {
35877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                digit = op - 90;
35887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (digit >= 0) {
35897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    work[op] = (byte) (digit % 10);
35907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bytecar[op] = (byte) (digit / 10); // calculate carry
35917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue op;
35927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
35937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // borrowing...
35947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                digit = digit + 100; // yes, this is right [consider -50]
35957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                work[op] = (byte) (digit % 10);
35967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %]
35977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
35987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* op */
35997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return work;
36007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
36017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
36037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Create a copy of BigDecimal object for local use. <p>This does NOT make a copy of the mantissa array.
36047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </sgml> Arg1 is the BigDecimal to clone (non-null)
36057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
36067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) {
36087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.math.BigDecimal copy;
36097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        copy = new com.ibm.icu.math.BigDecimal();
36107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        copy.ind = dec.ind;
36117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        copy.exp = dec.exp;
36127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        copy.form = dec.form;
36137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        copy.mant = dec.mant;
36147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return copy;
36157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
36167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
36187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Check one or two numbers for lost digits. </sgml> Arg1 is RHS (or null, if none) Arg2 is current DIGITS
36197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * setting returns quietly or throws an exception
36207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
36217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) {
36237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (dig == 0)
36247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return; // don't check if digits=0
36257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // first check lhs...
36267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (this.mant.length > dig)
36277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((!(allzero(this.mant, dig))))
36287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString());
36297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rhs == null)
36307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return; // monadic
36317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rhs.mant.length > dig)
36327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((!(allzero(rhs.mant, dig))))
36337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
36347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
36357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
36377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Round to specified digits, if necessary. </sgml> Arg1 is requested MathContext [with length and rounding
36387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * mode] returns this, for convenience
36397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
36407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) {
36427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return round(set.digits, set.roundingMode);
36437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
36447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
36467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when
36477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience
36482d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
36497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ind and exp are adjusted, but not cleared for a mantissa of zero
36502d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
36517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa
36527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * length will be 1. </sgml>
36537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
36547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private com.ibm.icu.math.BigDecimal round(int len, int mode) {
36567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int adjust;
36577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int sign;
36587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte oldmant[];
36597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean reuse = false;
36607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte first = 0;
36617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int increment;
36627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newmant[] = null;
36637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        adjust = mant.length - len;
36647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (adjust <= 0)
36657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return this; // nowt to do
36667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        exp = exp + adjust; // exponent of result
36682d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        sign = ind; // save [assumes -1, 0, 1]
36697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        oldmant = mant; // save
36707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (len > 0) {
36717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // remove the unwanted digits
36727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mant = new byte[len];
36732d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            java.lang.System.arraycopy(oldmant, 0, mant, 0, len);
36747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            reuse = true; // can reuse mantissa
36757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            first = oldmant[len]; // first of discarded digits
36767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {/* len<=0 */
36777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mant = ZERO.mant;
36787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ind = iszero;
36797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            reuse = false; // cannot reuse mantissa
36807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (len == 0)
36817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                first = oldmant[0];
36827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else
36837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                first = (byte) 0; // [virtual digit]
36847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
36857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
36867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // decide rounding adjustment depending on mode, sign, and discarded digits
36877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        increment = 0; // bumper
36887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
36897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {/* select */
36907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (mode == ROUND_HALF_UP) { // default first [most common]
36917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (first >= 5)
36927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        increment = sign;
36937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_UNNECESSARY) { // default for setScale()
36947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // discarding any non-zero digits is an error
36957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if ((!(allzero(oldmant, len))))
36967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        throw new java.lang.ArithmeticException("Rounding necessary");
36977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down
36987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (first > 5)
36997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        increment = sign;
37007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else if (first == 5)
37017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((!(allzero(oldmant, len + 1))))
37027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            increment = sign;
37037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even
37047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (first > 5)
37057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        increment = sign;
37067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    else if (first == 5) {
37077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((!(allzero(oldmant, len + 1))))
37087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            increment = sign;
37097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        else /* 0.5000 */
37107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((((mant[mant.length - 1]) % 2)) != 0)
37117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            increment = sign;
37127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
37137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_DOWN) {
37147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // never increment
37157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_UP) { // increment if discarded non-zero
37167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if ((!(allzero(oldmant, len))))
37177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        increment = sign;
37187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_CEILING) { // more positive
37197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (sign > 0)
37207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((!(allzero(oldmant, len))))
37217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            increment = sign;
37227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (mode == ROUND_FLOOR) { // more negative
37237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (sign < 0)
37247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((!(allzero(oldmant, len))))
37257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            increment = sign;
37267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
37277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode);
37287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
37297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
37307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* modes */
37317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
37327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (increment != 0) {
37337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {
37347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (ind == iszero) {
37357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // we must not subtract from 0, but result is trivial anyway
37367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    mant = ONE.mant;
37377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ind = (byte) increment;
37387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
37397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // mantissa is non-0; we can safely add or subtract 1
37407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (ind == isneg)
37417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        increment = -increment;
37427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse);
37437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (newmant.length > mant.length) { // had a carry
37447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // drop rightmost digit and raise exponent
37457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        exp++;
37467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // mant is already the correct length
37472d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                        java.lang.System.arraycopy(newmant, 0, mant, 0,
37487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                mant.length);
37497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } else
37507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        mant = newmant;
37517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
37527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while (false);
37537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* bump */
37547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // rounding can increase exponent significantly
37557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (exp > MaxExp)
37567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
37577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this;
37587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
37597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
37607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
37617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to
37627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0
37632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert     *
37647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Arg2 may be beyond array bounds, in which case 1 is returned </sgml>
37657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
37667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
37677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final boolean allzero(byte array[], int start) {
37687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
37697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (start < 0)
37707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            start = 0;
37717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
37727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $25 = array.length - 1;
37737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = start;
37747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; i <= $25; i++) {
37757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (array[i] != 0)
37767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return false;
37777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
37787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
37797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return true;
37807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
37817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
37827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
37837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <sgml> Carry out final checks and canonicalization <p> This finishes off the current number by: 1. Rounding if
37847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping
37857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0'
37867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. </sgml> Arg1 is requested
37877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed
37887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience
37897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
37907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
37917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) {
37927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int d = 0;
37937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
37947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        byte newmant[] = null;
37957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int mag = 0;
37967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int sig = 0;
37977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Round if mantissa too long and digits requested */
37987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (set.digits != 0)
37997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this.mant.length > set.digits)
38007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                this.round(set);
38017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
38027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
38037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * If strip requested (and standard formatting), remove insignificant trailing zeros.
38047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
38057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (strip)
38067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (set.form != com.ibm.icu.math.MathContext.PLAIN) {
38077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                d = this.mant.length;
38087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                /* see if we need to drop any trailing zeros */
38097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {
38107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i = d - 1;
38117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    i: for (; i >= 1; i--) {
38127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (this.mant[i] != 0)
38137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            break i;
38147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        d--;
38157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        exp++;
38167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
38177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }/* i */
38187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (d < this.mant.length) {/* need to reduce */
38197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newmant = new byte[d];
38202d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                    java.lang.System.arraycopy(this.mant, 0, newmant, 0, d);
38217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    this.mant = newmant;
38227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
38237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
38247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
38257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset
38267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
38277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* Now check for leading- and all- zeros in mantissa */
38287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
38297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int $26 = this.mant.length;
38307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            i = 0;
38317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (; $26 > 0; $26--, i++) {
38327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (this.mant[i] != 0) {
38337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // non-0 result; ind will be correct
38347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // remove leading zeros [e.g., after subtract]
38357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (i > 0) {
38367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        do {
38377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            newmant = new byte[this.mant.length - i];
38382d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert                            java.lang.System.arraycopy(this.mant, i, newmant, 0,
38397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    this.mant.length - i);
38407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            this.mant = newmant;
38417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } while (false);
38427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }/* delead */
38437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // now determine form if not PLAIN
38447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    mag = exp + mant.length;
38457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (mag > 0) { // most common path
38467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (mag > set.digits)
38477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (set.digits != 0)
38487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                form = (byte) set.form;
38497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if ((mag - 1) <= MaxExp)
38507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            return this; // no overflow; quick return
38517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } else if (mag < (-5))
38527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        form = (byte) set.form;
38537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    /* check for overflow */
38547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    mag--;
38557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if ((mag < MinExp) | (mag > MaxExp)) {
38567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        overflow: do {
38577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            // possible reprieve if form is engineering
38587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            if (form == com.ibm.icu.math.MathContext.ENGINEERING) {
38597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                sig = mag % 3; // leftover
38607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                if (sig < 0)
38617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    sig = 3 + sig; // negative exponent
38627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                mag = mag - sig; // exponent to use
38637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                // 1999.06.29: second test here must be MaxExp
38647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                if (mag >= MinExp)
38657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    if (mag <= MaxExp)
38667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        break overflow;
38677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            }
38687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag);
38697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        } while (false);
38707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }/* overflow */
38717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return this;
38727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
38737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
38747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }/* i */
38757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
38767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Drop through to here only if mantissa is all zeros
38777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ind = iszero;
38787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/* select */
38797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
38807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                exp = 0; // standard result; go to '0'
38817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else if (exp > 0)
38827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                exp = 0; // +ve exponent also goes to '0'
38837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
38847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // a plain number with -ve exponent; preserve and check exponent
38857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (exp < MinExp)
38867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
38877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
38887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
38897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        mant = ZERO.mant; // canonical mantissa
38907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this;
38917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
38927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
3893