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")) => "4.40" 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40" 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80" 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <br>new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2" 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </code> 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * where the value on the right of the <code>=></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 -> 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>*</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