-//##header\r
-/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */\r
-/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */\r
-package com.ibm.icu.math;\r
-import java.math.BigInteger;\r
-import com.ibm.icu.impl.Utility;\r
-import com.ibm.icu.lang.UCharacter;\r
-\r
-/* ------------------------------------------------------------------ */\r
-/* BigDecimal -- Decimal arithmetic for Java */\r
-/* ------------------------------------------------------------------ */\r
-/* Copyright IBM Corporation, 1996-2009. All Rights Reserved. */\r
-/* */\r
-/* The BigDecimal class provides immutable arbitrary-precision */\r
-/* floating point (including integer) decimal numbers. */\r
-/* */\r
-/* As the numbers are decimal, there is an exact correspondence */\r
-/* between an instance of a BigDecimal object and its String */\r
-/* representation; the BigDecimal class provides direct conversions */\r
-/* to and from String and character array objects, and well as */\r
-/* conversions to and from the Java primitive types (which may not */\r
-/* be exact). */\r
-/* ------------------------------------------------------------------ */\r
-/* Notes: */\r
-/* */\r
-/* 1. A BigDecimal object is never changed in value once constructed; */\r
-/* this avoids the need for locking. Note in particular that the */\r
-/* mantissa array may be shared between many BigDecimal objects, */\r
-/* so that once exposed it must not be altered. */\r
-/* */\r
-/* 2. This class looks at MathContext class fields directly (for */\r
-/* performance). It must not and does not change them. */\r
-/* */\r
-/* 3. Exponent checking is delayed until finish(), as we know */\r
-/* intermediate calculations cannot cause 31-bit overflow. */\r
-/* [This assertion depends on MAX_DIGITS in MathContext.] */\r
-/* */\r
-/* 4. Comments for the public API now follow the javadoc conventions. */\r
-/* The NetRexx -comments option is used to pass these comments */\r
-/* through to the generated Java code (with -format, if desired). */\r
-/* */\r
-/* 5. System.arraycopy is faster than explicit loop as follows */\r
-/* Mean length 4: equal */\r
-/* Mean length 8: x2 */\r
-/* Mean length 16: x3 */\r
-/* Mean length 24: x4 */\r
-/* From prior experience, we expect mean length a little below 8, */\r
-/* but arraycopy is still the one to use, in general, until later */\r
-/* measurements suggest otherwise. */\r
-/* */\r
-/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */\r
-/* assembler code implementation of the algorithms below; it is */\r
-/* now called IXXRCN and is available with the OS/390 and VM/ESA */\r
-/* operating systems. */\r
-/* ------------------------------------------------------------------ */\r
-/* Change History: */\r
-/* 1997.09.02 Initial version (derived from netrexx.lang classes) */\r
-/* 1997.09.12 Add lostDigits checking */\r
-/* 1997.10.06 Change mantissa to a byte array */\r
-/* 1997.11.22 Rework power [did not prepare arguments, etc.] */\r
-/* 1997.12.13 multiply did not prepare arguments */\r
-/* 1997.12.14 add did not prepare and align arguments correctly */\r
-/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */\r
-/* 1998.05.21 adjust remainder operator finalization */\r
-/* 1998.06.04 rework to pass MathContext to finish() and round() */\r
-/* 1998.06.06 change format to use round(); support rounding modes */\r
-/* 1998.06.25 rename to BigDecimal and begin merge */\r
-/* zero can now have trailing zeros (i.e., exp\=0) */\r
-/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */\r
-/* unscaledValue, valueof */\r
-/* 1998.07.01 improve byteaddsub to allow array reuse, etc. */\r
-/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */\r
-/* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */\r
-/* 1998.07.08 setScale, faster equals */\r
-/* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */\r
-/* 1998.10.12 change package to com.ibm.icu.math */\r
-/* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */\r
-/* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */\r
-/* 1998.12.29 improve byteaddsub by using table lookup */\r
-/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */\r
-/* 1999.02.05 cleaner code for BigDecimal(char[]) */\r
-/* 1999.02.06 add javadoc comments */\r
-/* 1999.02.11 format() changed from 7 to 2 method form */\r
-/* 1999.03.05 null pointer checking is no longer explicit */\r
-/* 1999.03.05 simplify; changes from discussion with J. Bloch: */\r
-/* null no longer permitted for MathContext; drop boolean, */\r
-/* byte, char, float, short constructor, deprecate double */\r
-/* constructor, no blanks in string constructor, add */\r
-/* offset and length version of char[] constructor; */\r
-/* add valueOf(double); drop booleanValue, charValue; */\r
-/* add ...Exact versions of remaining convertors */\r
-/* 1999.03.13 add toBigIntegerExact */\r
-/* 1999.03.13 1.00 release to IBM Centre for Java Technology */\r
-/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */\r
-/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */\r
-/* 1999.07.03 1.03 lost digits should not be checked if digits=0 */\r
-/* 1999.07.06 lost digits Exception message changed */\r
-/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */\r
-/* 1999.07.17 improve messages from pow method */\r
-/* 1999.08.08 performance tweaks */\r
-/* 1999.08.15 fastpath in multiply */\r
-/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */\r
-/* 1999.12.22 1.06 remove multiply fastpath, and improve performance */\r
-/* 2000.01.01 copyright update [Y2K has arrived] */\r
-/* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */\r
-/* ------------------------------------------------------------------ */\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- * The <code>BigDecimal</code> class implements immutable\r
- * arbitrary-precision decimal numbers. The methods of the\r
- * <code>BigDecimal</code> class provide operations for fixed and\r
- * floating point arithmetic, comparison, format conversions, and\r
- * hashing.\r
- * <p>\r
- * As the numbers are decimal, there is an exact correspondence between\r
- * an instance of a <code>BigDecimal</code> object and its\r
- * <code>String</code> representation; the <code>BigDecimal</code> class\r
- * provides direct conversions to and from <code>String</code> and\r
- * character array (<code>char[]</code>) objects, as well as conversions\r
- * to and from the Java primitive types (which may not be exact) and\r
- * <code>BigInteger</code>.\r
- * <p>\r
- * In the descriptions of constructors and methods in this documentation,\r
- * the value of a <code>BigDecimal</code> number object is shown as the\r
- * result of invoking the <code>toString()</code> method on the object.\r
- * The internal representation of a decimal number is neither defined\r
- * nor exposed, and is not permitted to affect the result of any\r
- * operation.\r
- * <p>\r
- * The floating point arithmetic provided by this class is defined by\r
- * the ANSI X3.274-1996 standard, and is also documented at\r
- * <code>http://www2.hursley.ibm.com/decimal</code>\r
- * <br><i>[This URL will change.]</i>\r
- *\r
- * <h3>Operator methods</h3>\r
- * <p>\r
- * Operations on <code>BigDecimal</code> numbers are controlled by a\r
- * {@link MathContext} object, which provides the context (precision and\r
- * other information) for the operation. Methods that can take a\r
- * <code>MathContext</code> parameter implement the standard arithmetic\r
- * operators for <code>BigDecimal</code> objects and are known as\r
- * <i>operator methods</i>. The default settings provided by the\r
- * constant {@link MathContext#DEFAULT} (<code>digits=9,\r
- * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>)\r
- * perform general-purpose floating point arithmetic to nine digits of\r
- * precision. The <code>MathContext</code> parameter must not be\r
- * <code>null</code>.\r
- * <p>\r
- * Each operator method also has a version provided which does\r
- * not take a <code>MathContext</code> parameter. For this version of\r
- * each method, the context settings used are <code>digits=0,\r
- * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>;\r
- * these settings perform fixed point arithmetic with unlimited\r
- * precision, as defined for the original BigDecimal class in Java 1.1\r
- * and Java 1.2.\r
- * <p>\r
- * For monadic operators, only the optional <code>MathContext</code>\r
- * parameter is present; the operation acts upon the current object.\r
- * <p>\r
- * For dyadic operators, a <code>BigDecimal</code> parameter is always\r
- * present; it must not be <code>null</code>.\r
- * The operation acts with the current object being the left-hand operand\r
- * and the <code>BigDecimal</code> parameter being the right-hand operand.\r
- * <p>\r
- * For example, adding two <code>BigDecimal</code> objects referred to\r
- * by the names <code>award</code> and <code>extra</code> could be\r
- * written as any of:\r
- * <p><code>\r
- * award.add(extra)\r
- * <br>award.add(extra, MathContext.DEFAULT)\r
- * <br>award.add(extra, acontext)\r
- * </code>\r
- * <p>\r
- * (where <code>acontext</code> is a <code>MathContext</code> object),\r
- * which would return a <code>BigDecimal</code> object whose value is\r
- * the result of adding <code>award</code> and <code>extra</code> under\r
- * the appropriate context settings.\r
- * <p>\r
- * When a <code>BigDecimal</code> operator method is used, a set of\r
- * rules define what the result will be (and, by implication, how the\r
- * result would be represented as a character string).\r
- * These rules are defined in the BigDecimal arithmetic documentation\r
- * (see the URL above), but in summary:\r
- * <ul>\r
- * <li>Results are normally calculated with up to some maximum number of\r
- * significant digits.\r
- * For example, if the <code>MathContext</code> parameter for an operation\r
- * were <code>MathContext.DEFAULT</code> then the result would be\r
- * rounded to 9 digits; the division of 2 by 3 would then result in\r
- * 0.666666667.\r
- * <br>\r
- * You can change the default of 9 significant digits by providing the\r
- * method with a suitable <code>MathContext</code> object. This lets you\r
- * calculate using as many digits as you need -- thousands, if necessary.\r
- * Fixed point (scaled) arithmetic is indicated by using a\r
- * <code>digits</code> setting of 0 (or omitting the\r
- * <code>MathContext</code> parameter).\r
- * <br>\r
- * Similarly, you can change the algorithm used for rounding from the\r
- * default "classic" algorithm.\r
- * <li>\r
- * In standard arithmetic (that is, when the <code>form</code> setting\r
- * is not <code>PLAIN</code>), a zero result is always expressed as the\r
- * single digit <code>'0'</code> (that is, with no sign, decimal point,\r
- * or exponent part).\r
- * <li>\r
- * Except for the division and power operators in standard arithmetic,\r
- * trailing zeros are preserved (this is in contrast to binary floating\r
- * point operations and most electronic calculators, which lose the\r
- * information about trailing zeros in the fractional part of results).\r
- * <br>\r
- * So, for example:\r
- * <p><code>\r
- * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40"\r
- * <br>new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40"\r
- * <br>new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80"\r
- * <br>new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2"\r
- * </code>\r
- * <p>where the value on the right of the <code>=></code> would be the\r
- * result of the operation, expressed as a <code>String</code>, and\r
- * <code>def</code> (in this and following examples) refers to\r
- * <code>MathContext.DEFAULT</code>).\r
- * This preservation of trailing zeros is desirable for most\r
- * calculations (including financial calculations).\r
- * If necessary, trailing zeros may be easily removed using division by 1.\r
- * <li>\r
- * In standard arithmetic, exponential form is used for a result\r
- * depending on its value and the current setting of <code>digits</code>\r
- * (the default is 9 digits).\r
- * If the number of places needed before the decimal point exceeds the\r
- * <code>digits</code> setting, or the absolute value of the number is\r
- * less than <code>0.000001</code>, then the number will be expressed in\r
- * exponential notation; thus\r
- * <p><code>\r
- * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)\r
- * </code>\r
- * <p>results in <code>1E+12</code> instead of\r
- * <code>1000000000000</code>, and\r
- * <p><code>\r
- * new BigDecimal("1").divide(new BigDecimal("3E+10"), def)\r
- * </code>\r
- * <p>results in <code>3.33333333E-11</code> instead of\r
- * <code>0.0000000000333333333</code>.\r
- * <p>\r
- * The form of the exponential notation (scientific or engineering) is\r
- * determined by the <code>form</code> setting.\r
- * <eul>\r
- * <p>\r
- * The names of methods in this class follow the conventions established\r
- * by <code>java.lang.Number</code>, <code>java.math.BigInteger</code>,\r
- * and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.\r
- *\r
- * @see MathContext\r
- * @author Mike Cowlishaw\r
- * @stable ICU 2.0\r
- */\r
-\r
-public class BigDecimal extends java.lang.Number implements java.io.Serializable,java.lang.Comparable{\r
- //private static final java.lang.String $0="BigDecimal.nrx";\r
- \r
- \r
- \r
- /* ----- Constants ----- */\r
- /* properties constant public */ // useful to others\r
- /**\r
- * The <code>BigDecimal</code> constant "0".\r
- *\r
- * @see #ONE\r
- * @see #TEN\r
- * @stable ICU 2.0\r
- */\r
- public static final com.ibm.icu.math.BigDecimal ZERO=new com.ibm.icu.math.BigDecimal((long)0); // use long as we want the int constructor\r
- // .. to be able to use this, for speed\r
- \r
- /**\r
- * The <code>BigDecimal</code> constant "1".\r
- *\r
- * @see #TEN\r
- * @see #ZERO\r
- * @stable ICU 2.0\r
- */\r
- public static final com.ibm.icu.math.BigDecimal ONE=new com.ibm.icu.math.BigDecimal((long)1); // use long as we want the int constructor\r
- // .. to be able to use this, for speed\r
- \r
- /**\r
- * The <code>BigDecimal</code> constant "10".\r
- *\r
- * @see #ONE\r
- * @see #ZERO\r
- * @stable ICU 2.0\r
- */\r
- public static final com.ibm.icu.math.BigDecimal TEN=new com.ibm.icu.math.BigDecimal(10);\r
- \r
- // the rounding modes (copied here for upwards compatibility)\r
- /**\r
- * Rounding mode to round to a more positive number.\r
- * @see MathContext#ROUND_CEILING\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_CEILING=com.ibm.icu.math.MathContext.ROUND_CEILING;\r
- \r
- /**\r
- * Rounding mode to round towards zero.\r
- * @see MathContext#ROUND_DOWN\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_DOWN=com.ibm.icu.math.MathContext.ROUND_DOWN;\r
- \r
- /**\r
- * Rounding mode to round to a more negative number.\r
- * @see MathContext#ROUND_FLOOR\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_FLOOR=com.ibm.icu.math.MathContext.ROUND_FLOOR;\r
- \r
- /**\r
- * Rounding mode to round to nearest neighbor, where an equidistant\r
- * value is rounded down.\r
- * @see MathContext#ROUND_HALF_DOWN\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_HALF_DOWN=com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;\r
- \r
- /**\r
- * Rounding mode to round to nearest neighbor, where an equidistant\r
- * value is rounded to the nearest even neighbor.\r
- * @see MathContext#ROUND_HALF_EVEN\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_HALF_EVEN=com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;\r
- \r
- /**\r
- * Rounding mode to round to nearest neighbor, where an equidistant\r
- * value is rounded up.\r
- * @see MathContext#ROUND_HALF_UP\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_HALF_UP=com.ibm.icu.math.MathContext.ROUND_HALF_UP;\r
- \r
- /**\r
- * Rounding mode to assert that no rounding is necessary.\r
- * @see MathContext#ROUND_UNNECESSARY\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_UNNECESSARY=com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;\r
- \r
- /**\r
- * Rounding mode to round away from zero.\r
- * @see MathContext#ROUND_UP\r
- * @stable ICU 2.0\r
- */\r
- public static final int ROUND_UP=com.ibm.icu.math.MathContext.ROUND_UP;\r
- \r
- /* properties constant private */ // locals\r
- private static final byte ispos=1; // ind: indicates positive (must be 1)\r
- private static final byte iszero=0; // ind: indicates zero (must be 0)\r
- private static final byte isneg=-1; // ind: indicates negative (must be -1)\r
- // [later could add NaN, +/- infinity, here]\r
- \r
- private static final int MinExp=-999999999; // minimum exponent allowed\r
- private static final int MaxExp=999999999; // maximum exponent allowed\r
- private static final int MinArg=-999999999; // minimum argument integer\r
- private static final int MaxArg=999999999; // maximum argument integer\r
- \r
- private static final com.ibm.icu.math.MathContext plainMC=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math\r
- \r
- /* properties constant private unused */ // present but not referenced\r
- \r
- // Serialization version\r
- private static final long serialVersionUID=8245355804974198832L;\r
- \r
- //private static final java.lang.String copyright=" Copyright (c) IBM Corporation 1996, 2000. All rights reserved. ";\r
- \r
- /* properties static private */\r
- // Precalculated constant arrays (used by byteaddsub)\r
- private static byte bytecar[]=new byte[(90+99)+1]; // carry/borrow array\r
- private static byte bytedig[]=diginit(); // next digit array\r
- \r
- /* ----- Instance properties [all private and immutable] ----- */\r
- /* properties private */\r
- \r
- /**\r
- * The indicator. This may take the values:\r
- * <ul>\r
- * <li>ispos -- the number is positive\r
- * <li>iszero -- the number is zero\r
- * <li>isneg -- the number is negative\r
- * </ul>\r
- *\r
- * @serial\r
- */\r
- private byte ind; // assumed undefined\r
- // Note: some code below assumes IND = Sign [-1, 0, 1], at present.\r
- // We only need two bits for this, but use a byte [also permits\r
- // smooth future extension].\r
- \r
- /**\r
- * The formatting style. This may take the values:\r
- * <ul>\r
- * <li>MathContext.PLAIN -- no exponent needed\r
- * <li>MathContext.SCIENTIFIC -- scientific notation required\r
- * <li>MathContext.ENGINEERING -- engineering notation required\r
- * </ul>\r
- * <p>\r
- * This property is an optimization; it allows us to defer number\r
- * layout until it is actually needed as a string, hence avoiding\r
- * unnecessary formatting.\r
- *\r
- * @serial\r
- */\r
- private byte form=(byte)com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN\r
- // We only need two bits for this, at present, but use a byte\r
- // [again, to allow for smooth future extension]\r
- \r
- /**\r
- * The value of the mantissa.\r
- * <p>\r
- * Once constructed, this may become shared between several BigDecimal\r
- * objects, so must not be altered.\r
- * <p>\r
- * For efficiency (speed), this is a byte array, with each byte\r
- * taking a value of 0 -> 9.\r
- * <p>\r
- * If the first byte is 0 then the value of the number is zero (and\r
- * mant.length=1, except when constructed from a plain number, for\r
- * example, 0.000).\r
- *\r
- * @serial\r
- */\r
- private byte mant[]; // assumed null\r
- \r
- /**\r
- * The exponent.\r
- * <p>\r
- * For fixed point arithmetic, scale is <code>-exp</code>, and can\r
- * apply to zero.\r
- *\r
- * Note that this property can have a value less than MinExp when\r
- * the mantissa has more than one digit.\r
- *\r
- * @serial\r
- */\r
- private int exp;\r
- // assumed 0\r
- \r
- /* ---------------------------------------------------------------- */\r
- /* Constructors */\r
- /* ---------------------------------------------------------------- */\r
- \r
-//#if defined(FOUNDATION10)\r
-//#else\r
- /**\r
- * Constructs a <code>BigDecimal</code> object from a\r
- * <code>java.math.BigDecimal</code>.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> as though the parameter had\r
- * been represented as a <code>String</code> (using its\r
- * <code>toString</code> method) and the\r
- * {@link #BigDecimal(java.lang.String)} constructor had then been\r
- * used.\r
- * The parameter must not be <code>null</code>.\r
- * <p>\r
- * <i>(Note: this constructor is provided only in the\r
- * <code>com.ibm.icu.math</code> version of the BigDecimal class.\r
- * It would not be present in a <code>java.math</code> version.)</i>\r
- *\r
- * @param bd The <code>BigDecimal</code> to be translated.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(java.math.BigDecimal bd){\r
- this(bd.toString());\r
- return;}\r
-//#endif\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object from a\r
- * <code>BigInteger</code>, with scale 0.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> which is the exact decimal\r
- * representation of the <code>BigInteger</code>, with a scale of\r
- * zero.\r
- * The value of the <code>BigDecimal</code> is identical to the value\r
- * of the <code>BigInteger</code>.\r
- * The parameter must not be <code>null</code>.\r
- * <p>\r
- * The <code>BigDecimal</code> will contain only decimal digits,\r
- * prefixed with a leading minus sign (hyphen) if the\r
- * <code>BigInteger</code> is negative. A leading zero will be\r
- * present only if the <code>BigInteger</code> is zero.\r
- *\r
- * @param bi The <code>BigInteger</code> to be converted.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(java.math.BigInteger bi){\r
- this(bi.toString(10));\r
- return;}\r
- // exp remains 0\r
- \r
- /**\r
- * Constructs a <code>BigDecimal</code> object from a\r
- * <code>BigInteger</code> and a scale.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> which is the exact decimal\r
- * representation of the <code>BigInteger</code>, scaled by the\r
- * second parameter, which may not be negative.\r
- * The value of the <code>BigDecimal</code> is the\r
- * <code>BigInteger</code> divided by ten to the power of the scale.\r
- * The <code>BigInteger</code> parameter must not be\r
- * <code>null</code>.\r
- * <p>\r
- * The <code>BigDecimal</code> will contain only decimal digits, (with\r
- * an embedded decimal point followed by <code>scale</code> decimal\r
- * digits if the scale is positive), prefixed with a leading minus\r
- * sign (hyphen) if the <code>BigInteger</code> is negative. A\r
- * leading zero will be present only if the <code>BigInteger</code> is\r
- * zero.\r
- *\r
- * @param bi The <code>BigInteger</code> to be converted.\r
- * @param scale The <code>int</code> specifying the scale.\r
- * @throws NumberFormatException if the scale is negative.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(java.math.BigInteger bi,int scale){\r
- this(bi.toString(10));\r
- if (scale<0) \r
- throw new java.lang.NumberFormatException("Negative scale:"+" "+scale);\r
- exp=(int)-scale; // exponent is -scale\r
- return;}\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object from an array of characters.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> as though a\r
- * <code>String</code> had been constructed from the character array\r
- * and the {@link #BigDecimal(java.lang.String)} constructor had then\r
- * been used. The parameter must not be <code>null</code>.\r
- * <p>\r
- * Using this constructor is faster than using the\r
- * <code>BigDecimal(String)</code> constructor if the string is\r
- * already available in character array form.\r
- *\r
- * @param inchars The <code>char[]</code> array containing the number\r
- * to be converted.\r
- * @throws NumberFormatException if the parameter is not a valid\r
- * number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(char inchars[]){\r
- this(inchars,0,inchars.length);\r
- return;}\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object from an array of characters.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> as though a\r
- * <code>String</code> had been constructed from the character array\r
- * (or a subarray of that array) and the\r
- * {@link #BigDecimal(java.lang.String)} constructor had then been\r
- * used. The first parameter must not be <code>null</code>, and the\r
- * subarray must be wholly contained within it.\r
- * <p>\r
- * Using this constructor is faster than using the\r
- * <code>BigDecimal(String)</code> constructor if the string is\r
- * already available within a character array.\r
- *\r
- * @param inchars The <code>char[]</code> array containing the number\r
- * to be converted.\r
- * @param offset The <code>int</code> offset into the array of the\r
- * start of the number to be converted.\r
- * @param length The <code>int</code> length of the number.\r
- * @throws NumberFormatException if the parameter is not a valid\r
- * number for any reason.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(char inchars[],int offset,int length){super();\r
- boolean exotic;\r
- boolean hadexp;\r
- int d;\r
- int dotoff;\r
- int last;\r
- int i=0;\r
- char si=0;\r
- boolean eneg=false;\r
- int k=0;\r
- int elen=0;\r
- int j=0;\r
- char sj=0;\r
- int dvalue=0;\r
- int mag=0;\r
- // This is the primary constructor; all incoming strings end up\r
- // here; it uses explicit (inline) parsing for speed and to avoid\r
- // generating intermediate (temporary) objects of any kind.\r
- // 1998.06.25: exponent form built only if E/e in string\r
- // 1998.06.25: trailing zeros not removed for zero\r
- // 1999.03.06: no embedded blanks; allow offset and length\r
- if (length<=0) \r
- bad(inchars); // bad conversion (empty string)\r
- // [bad offset will raise array bounds exception]\r
- \r
- /* Handle and step past sign */\r
- ind=ispos; // assume positive\r
- if (inchars[offset]==('-')) \r
- {\r
- length--;\r
- if (length==0) \r
- bad(inchars); // nothing after sign\r
- ind=isneg;\r
- offset++;\r
- }\r
- else \r
- if (inchars[offset]==('+')) \r
- {\r
- length--;\r
- if (length==0) \r
- bad(inchars); // nothing after sign\r
- offset++;\r
- }\r
- \r
- /* We're at the start of the number */\r
- exotic=false; // have extra digits\r
- hadexp=false; // had explicit exponent\r
- d=0; // count of digits found\r
- dotoff=-1; // offset where dot was found\r
- last=-1; // last character of mantissa\r
- {int $1=length;i=offset;i:for(;$1>0;$1--,i++){\r
- si=inchars[i];\r
- if (si>='0') // test for Arabic digit\r
- if (si<='9') \r
- {\r
- last=i;\r
- d++; // still in mantissa\r
- continue i;\r
- }\r
- if (si=='.') \r
- { // record and ignore\r
- if (dotoff>=0) \r
- bad(inchars); // two dots\r
- dotoff=i-offset; // offset into mantissa\r
- continue i;\r
- }\r
- if (si!='e') \r
- if (si!='E') \r
- { // expect an extra digit\r
- if ((!(UCharacter.isDigit(si)))) \r
- bad(inchars); // not a number\r
- // defer the base 10 check until later to avoid extra method call\r
- exotic=true; // will need conversion later\r
- last=i;\r
- d++; // still in mantissa\r
- continue i;\r
- }\r
- /* Found 'e' or 'E' -- now process explicit exponent */\r
- // 1998.07.11: sign no longer required\r
- if ((i-offset)>(length-2)) \r
- bad(inchars); // no room for even one digit\r
- eneg=false;\r
- if ((inchars[i+1])==('-')) \r
- {\r
- eneg=true;\r
- k=i+2;\r
- }\r
- else \r
- if ((inchars[i+1])==('+')) \r
- k=i+2;\r
- else \r
- k=i+1;\r
- // k is offset of first expected digit\r
- elen=length-((k-offset)); // possible number of digits\r
- if ((elen==0)|(elen>9)) \r
- bad(inchars); // 0 or more than 9 digits\r
- {int $2=elen;j=k;for(;$2>0;$2--,j++){\r
- sj=inchars[j];\r
- if (sj<'0') \r
- bad(inchars); // always bad\r
- if (sj>'9') \r
- { // maybe an exotic digit\r
- if ((!(UCharacter.isDigit(sj)))) \r
- bad(inchars); // not a number\r
- dvalue=UCharacter.digit(sj,10); // check base\r
- if (dvalue<0) \r
- bad(inchars); // not base 10\r
- }\r
- else \r
- dvalue=((int)(sj))-((int)('0'));\r
- exp=(exp*10)+dvalue;\r
- }\r
- }/*j*/\r
- if (eneg) \r
- exp=(int)-exp; // was negative\r
- hadexp=true; // remember we had one\r
- break i; // we are done\r
- }\r
- }/*i*/\r
- \r
- /* Here when all inspected */\r
- if (d==0) \r
- bad(inchars); // no mantissa digits\r
- if (dotoff>=0) \r
- exp=(exp+dotoff)-d; // adjust exponent if had dot\r
- \r
- /* strip leading zeros/dot (leave final if all 0's) */\r
- {int $3=last-1;i=offset;i:for(;i<=$3;i++){\r
- si=inchars[i];\r
- if (si=='0') \r
- {\r
- offset++;\r
- dotoff--;\r
- d--;\r
- }\r
- else \r
- if (si=='.') \r
- {\r
- offset++; // step past dot\r
- dotoff--;\r
- }\r
- else \r
- if (si<='9') \r
- break i;/* non-0 */\r
- else \r
- {/* exotic */\r
- if ((UCharacter.digit(si,10))!=0) \r
- break i; // non-0 or bad\r
- // is 0 .. strip like '0'\r
- offset++;\r
- dotoff--;\r
- d--;\r
- }\r
- }\r
- }/*i*/\r
- \r
- /* Create the mantissa array */\r
- mant=new byte[d]; // we know the length\r
- j=offset; // input offset\r
- if (exotic) \r
- {do{ // slow: check for exotica\r
- {int $4=d;i=0;for(;$4>0;$4--,i++){\r
- if (i==dotoff) \r
- j++; // at dot\r
- sj=inchars[j];\r
- if (sj<='9') \r
- mant[i]=(byte)(((int)(sj))-((int)('0')));/* easy */\r
- else \r
- {\r
- dvalue=UCharacter.digit(sj,10);\r
- if (dvalue<0) \r
- bad(inchars); // not a number after all\r
- mant[i]=(byte)dvalue;\r
- }\r
- j++;\r
- }\r
- }/*i*/\r
- }while(false);}/*exotica*/\r
- else \r
- {do{\r
- {int $5=d;i=0;for(;$5>0;$5--,i++){\r
- if (i==dotoff) \r
- j++;\r
- mant[i]=(byte)(((int)(inchars[j]))-((int)('0')));\r
- j++;\r
- }\r
- }/*i*/\r
- }while(false);}/*simple*/\r
- \r
- /* Looks good. Set the sign indicator and form, as needed. */\r
- // Trailing zeros are preserved\r
- // The rule here for form is:\r
- // If no E-notation, then request plain notation\r
- // Otherwise act as though add(0,DEFAULT) and request scientific notation\r
- // [form is already PLAIN]\r
- if (mant[0]==0) \r
- {\r
- ind=iszero; // force to show zero\r
- // negative exponent is significant (e.g., -3 for 0.000) if plain\r
- if (exp>0) \r
- exp=0; // positive exponent can be ignored\r
- if (hadexp) \r
- { // zero becomes single digit from add\r
- mant=ZERO.mant;\r
- exp=0;\r
- }\r
- }\r
- else \r
- { // non-zero\r
- // [ind was set earlier]\r
- // now determine form\r
- if (hadexp) \r
- {\r
- form=(byte)com.ibm.icu.math.MathContext.SCIENTIFIC;\r
- // 1999.06.29 check for overflow\r
- mag=(exp+mant.length)-1; // true exponent in scientific notation\r
- if ((mag<MinExp)|(mag>MaxExp)) \r
- bad(inchars);\r
- }\r
- }\r
- // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form\r
- return;\r
- }\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object directly from a\r
- * <code>double</code>.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> which is the exact decimal\r
- * representation of the 64-bit signed binary floating point\r
- * parameter.\r
- * <p>\r
- * Note that this constructor it an exact conversion; it does not give\r
- * the same result as converting <code>num</code> to a\r
- * <code>String</code> using the <code>Double.toString()</code> method\r
- * and then using the {@link #BigDecimal(java.lang.String)}\r
- * constructor.\r
- * To get that result, use the static {@link #valueOf(double)}\r
- * method to construct a <code>BigDecimal</code> from a\r
- * <code>double</code>.\r
- *\r
- * @param num The <code>double</code> to be converted.\r
- * @throws NumberFormatException if the parameter is infinite or\r
- * not a number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(double num){\r
- // 1999.03.06: use exactly the old algorithm\r
- // 2000.01.01: note that this constructor does give an exact result,\r
- // so perhaps it should not be deprecated\r
- // 2000.06.18: no longer deprecated\r
-//#if defined(FOUNDATION10)\r
-//## this(String.valueOf(num));\r
-//#else\r
- this((new java.math.BigDecimal(num)).toString());\r
-//#endif\r
- return;}\r
- /**\r
- * Constructs a <code>BigDecimal</code> object directly from a\r
- * <code>int</code>.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> which is the exact decimal\r
- * representation of the 32-bit signed binary integer parameter.\r
- * The <code>BigDecimal</code> will contain only decimal digits,\r
- * prefixed with a leading minus sign (hyphen) if the parameter is\r
- * negative.\r
- * A leading zero will be present only if the parameter is zero.\r
- *\r
- * @param num The <code>int</code> to be converted.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(int num){super();\r
- int mun;\r
- int i=0;\r
- // We fastpath commoners\r
- if (num<=9) \r
- if (num>=(-9)) \r
- {do{\r
- // very common single digit case\r
- {/*select*/\r
- if (num==0)\r
- {\r
- mant=ZERO.mant;\r
- ind=iszero;\r
- }\r
- else if (num==1)\r
- {\r
- mant=ONE.mant;\r
- ind=ispos;\r
- }\r
- else if (num==(-1))\r
- {\r
- mant=ONE.mant;\r
- ind=isneg;\r
- }\r
- else{\r
- {\r
- mant=new byte[1];\r
- if (num>0) \r
- {\r
- mant[0]=(byte)num;\r
- ind=ispos;\r
- }\r
- else \r
- { // num<-1\r
- mant[0]=(byte)((int)-num);\r
- ind=isneg;\r
- }\r
- }\r
- }\r
- }\r
- return;\r
- }while(false);}/*singledigit*/\r
- \r
- /* We work on negative numbers so we handle the most negative number */\r
- if (num>0) \r
- {\r
- ind=ispos;\r
- num=(int)-num;\r
- }\r
- else \r
- ind=isneg;/* negative */ // [0 case already handled]\r
- // [it is quicker, here, to pre-calculate the length with\r
- // one loop, then allocate exactly the right length of byte array,\r
- // then re-fill it with another loop]\r
- mun=num; // working copy\r
- {i=9;i:for(;;i--){\r
- mun=mun/10;\r
- if (mun==0) \r
- break i;\r
- }\r
- }/*i*/\r
- // i is the position of the leftmost digit placed\r
- mant=new byte[10-i];\r
- {i=(10-i)-1;i:for(;;i--){\r
- mant[i]=(byte)-(((byte)(num%10)));\r
- num=num/10;\r
- if (num==0) \r
- break i;\r
- }\r
- }/*i*/\r
- return;\r
- }\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object directly from a\r
- * <code>long</code>.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> which is the exact decimal\r
- * representation of the 64-bit signed binary integer parameter.\r
- * The <code>BigDecimal</code> will contain only decimal digits,\r
- * prefixed with a leading minus sign (hyphen) if the parameter is\r
- * negative.\r
- * A leading zero will be present only if the parameter is zero.\r
- *\r
- * @param num The <code>long</code> to be converted.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(long num){super();\r
- long mun;\r
- int i=0;\r
- // Not really worth fastpathing commoners in this constructor [also,\r
- // we use this to construct the static constants].\r
- // This is much faster than: this(String.valueOf(num).toCharArray())\r
- /* We work on negative num so we handle the most negative number */\r
- if (num>0) \r
- {\r
- ind=ispos;\r
- num=(long)-num;\r
- }\r
- else \r
- if (num==0) \r
- ind=iszero;\r
- else \r
- ind=isneg;/* negative */\r
- mun=num;\r
- {i=18;i:for(;;i--){\r
- mun=mun/10;\r
- if (mun==0) \r
- break i;\r
- }\r
- }/*i*/\r
- // i is the position of the leftmost digit placed\r
- mant=new byte[19-i];\r
- {i=(19-i)-1;i:for(;;i--){\r
- mant[i]=(byte)-(((byte)(num%10)));\r
- num=num/10;\r
- if (num==0) \r
- break i;\r
- }\r
- }/*i*/\r
- return;\r
- }\r
-\r
- /**\r
- * Constructs a <code>BigDecimal</code> object from a <code>String</code>.\r
- * <p>\r
- * Constructs a <code>BigDecimal</code> from the parameter, which must\r
- * not be <code>null</code> and must represent a valid <i>number</i>,\r
- * as described formally in the documentation referred to\r
- * {@link BigDecimal above}.\r
- * <p>\r
- * In summary, numbers in <code>String</code> form must have at least\r
- * one digit, may have a leading sign, may have a decimal point, and\r
- * exponential notation may be used. They follow conventional syntax,\r
- * and may not contain blanks.\r
- * <p>\r
- * Some valid strings from which a <code>BigDecimal</code> might\r
- * be constructed are:\r
- * <pre>\r
- * "0" -- Zero\r
- * "12" -- A whole number\r
- * "-76" -- A signed whole number\r
- * "12.70" -- Some decimal places\r
- * "+0.003" -- Plus sign is allowed\r
- * "17." -- The same as 17\r
- * ".5" -- The same as 0.5\r
- * "4E+9" -- Exponential notation\r
- * "0.73e-7" -- Exponential notation\r
- * </pre>\r
- * <p>\r
- * (Exponential notation means that the number includes an optional\r
- * sign and a power of ten following an '</code>E</code>' that\r
- * indicates how the decimal point will be shifted. Thus the\r
- * <code>"4E+9"</code> above is just a short way of writing\r
- * <code>4000000000</code>, and the <code>"0.73e-7"</code> is short\r
- * for <code>0.000000073</code>.)\r
- * <p>\r
- * The <code>BigDecimal</code> constructed from the String is in a\r
- * standard form, with no blanks, as though the\r
- * {@link #add(BigDecimal)} method had been used to add zero to the\r
- * number with unlimited precision.\r
- * If the string uses exponential notation (that is, includes an\r
- * <code>e</code> or an <code>E</code>), then the\r
- * <code>BigDecimal</code> number will be expressed in scientific\r
- * notation (where the power of ten is adjusted so there is a single\r
- * non-zero digit to the left of the decimal point); in this case if\r
- * the number is zero then it will be expressed as the single digit 0,\r
- * and if non-zero it will have an exponent unless that exponent would\r
- * be 0. The exponent must fit in nine digits both before and after it\r
- * is expressed in scientific notation.\r
- * <p>\r
- * Any digits in the parameter must be decimal; that is,\r
- * <code>Character.digit(c, 10)</code> (where </code>c</code> is the\r
- * character in question) would not return -1.\r
- *\r
- * @param string The <code>String</code> to be converted.\r
- * @throws NumberFormatException if the parameter is not a valid\r
- * number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public BigDecimal(java.lang.String string){\r
- this(string.toCharArray(),0,string.length());\r
- return;}\r
-\r
- /* <sgml> Make a default BigDecimal object for local use. </sgml> */\r
- \r
- private BigDecimal(){super();\r
- return;\r
- }\r
-\r
- /* ---------------------------------------------------------------- */\r
- /* Operator methods [methods which take a context parameter] */\r
- /* ---------------------------------------------------------------- */\r
- \r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is the absolute\r
- * value of this <code>BigDecimal</code>.\r
- * <p>\r
- * The same as {@link #abs(MathContext)}, where the context is\r
- * <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will\r
- * be <code>this.scale()</code>\r
- *\r
- * @return A <code>BigDecimal</code> whose value is the absolute\r
- * value of this <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal abs(){\r
- return this.abs(plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is the absolute value\r
- * of this <code>BigDecimal</code>.\r
- * <p>\r
- * If the current object is zero or positive, then the same result as\r
- * invoking the {@link #plus(MathContext)} method with the same\r
- * parameter is returned.\r
- * Otherwise, the same result as invoking the\r
- * {@link #negate(MathContext)} method with the same parameter is\r
- * returned.\r
- *\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is the absolute\r
- * value of this <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set){\r
- if (this.ind==isneg) \r
- return this.negate(set);\r
- return this.plus(set);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this+rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #add(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * the maximum of the scales of the two operands.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the addition.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this+rhs</code>, using fixed point arithmetic.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs){\r
- return this.add(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.\r
- * <p>\r
- * Implements the addition (<b><code>+</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the addition.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this+rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- com.ibm.icu.math.BigDecimal lhs;\r
- int reqdig;\r
- com.ibm.icu.math.BigDecimal res;\r
- byte usel[];\r
- int usellen;\r
- byte user[];\r
- int userlen;\r
- int newlen=0;\r
- int tlen=0;\r
- int mult=0;\r
- byte t[]=null;\r
- int ia=0;\r
- int ib=0;\r
- int ea=0;\r
- int eb=0;\r
- byte ca=0;\r
- byte cb=0;\r
- /* determine requested digits and form */\r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- lhs=this; // name for clarity and proxy\r
- \r
- /* Quick exit for add floating 0 */\r
- // plus() will optimize to return same object if possible\r
- if (lhs.ind==0) \r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN) \r
- return rhs.plus(set);\r
- if (rhs.ind==0) \r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN) \r
- return lhs.plus(set);\r
- \r
- /* Prepare numbers (round, unless unlimited precision) */\r
- reqdig=set.digits; // local copy (heavily used)\r
- if (reqdig>0) \r
- {\r
- if (lhs.mant.length>reqdig) \r
- lhs=clone(lhs).round(set);\r
- if (rhs.mant.length>reqdig) \r
- rhs=clone(rhs).round(set);\r
- // [we could reuse the new LHS for result in this case]\r
- }\r
- \r
- res=new com.ibm.icu.math.BigDecimal(); // build result here\r
- \r
- /* Now see how much we have to pad or truncate lhs or rhs in order\r
- to align the numbers. If one number is much larger than the\r
- other, then the smaller cannot affect the answer [but we may\r
- still need to pad with up to DIGITS trailing zeros]. */\r
- // Note sign may be 0 if digits (reqdig) is 0\r
- // usel and user will be the byte arrays passed to the adder; we'll\r
- // use them on all paths except quick exits\r
- usel=lhs.mant;\r
- usellen=lhs.mant.length;\r
- user=rhs.mant;\r
- userlen=rhs.mant.length;\r
- {do{/*select*/\r
- if (lhs.exp==rhs.exp)\r
- {/* no padding needed */\r
- // This is the most common, and fastest, path\r
- res.exp=lhs.exp;\r
- }\r
- else if (lhs.exp>rhs.exp)\r
- { // need to pad lhs and/or truncate rhs\r
- newlen=(usellen+lhs.exp)-rhs.exp;\r
- /* If, after pad, lhs would be longer than rhs by digits+1 or\r
- more (and digits>0) then rhs cannot affect answer, so we only\r
- need to pad up to a length of DIGITS+1. */\r
- if (newlen>=((userlen+reqdig)+1)) \r
- if (reqdig>0) \r
- {\r
- // LHS is sufficient\r
- res.mant=usel;\r
- res.exp=lhs.exp;\r
- res.ind=lhs.ind;\r
- if (usellen<reqdig) \r
- { // need 0 padding\r
- res.mant=extend(lhs.mant,reqdig);\r
- res.exp=res.exp-((reqdig-usellen));\r
- }\r
- return res.finish(set,false);\r
- }\r
- // RHS may affect result\r
- res.exp=rhs.exp; // expected final exponent\r
- if (newlen>(reqdig+1)) \r
- if (reqdig>0) \r
- {\r
- // LHS will be max; RHS truncated\r
- tlen=(newlen-reqdig)-1; // truncation length\r
- userlen=userlen-tlen;\r
- res.exp=res.exp+tlen;\r
- newlen=reqdig+1;\r
- }\r
- if (newlen>usellen) \r
- usellen=newlen; // need to pad LHS\r
- }\r
- else{ // need to pad rhs and/or truncate lhs\r
- newlen=(userlen+rhs.exp)-lhs.exp;\r
- if (newlen>=((usellen+reqdig)+1)) \r
- if (reqdig>0) \r
- {\r
- // RHS is sufficient\r
- res.mant=user;\r
- res.exp=rhs.exp;\r
- res.ind=rhs.ind;\r
- if (userlen<reqdig) \r
- { // need 0 padding\r
- res.mant=extend(rhs.mant,reqdig);\r
- res.exp=res.exp-((reqdig-userlen));\r
- }\r
- return res.finish(set,false);\r
- }\r
- // LHS may affect result\r
- res.exp=lhs.exp; // expected final exponent\r
- if (newlen>(reqdig+1)) \r
- if (reqdig>0) \r
- {\r
- // RHS will be max; LHS truncated\r
- tlen=(newlen-reqdig)-1; // truncation length\r
- usellen=usellen-tlen;\r
- res.exp=res.exp+tlen;\r
- newlen=reqdig+1;\r
- }\r
- if (newlen>userlen) \r
- userlen=newlen; // need to pad RHS\r
- }\r
- }while(false);}/*padder*/\r
- \r
- /* OK, we have aligned mantissas. Now add or subtract. */\r
- // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive\r
- // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]\r
- // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]\r
- if (lhs.ind==iszero) \r
- res.ind=ispos;\r
- else \r
- res.ind=lhs.ind; // likely sign, all paths\r
- if (((lhs.ind==isneg)?1:0)==((rhs.ind==isneg)?1:0)) // same sign, 0 non-negative\r
- mult=1;\r
- else \r
- {do{ // different signs, so subtraction is needed\r
- mult=-1; // will cause subtract\r
- /* Before we can subtract we must determine which is the larger,\r
- as our add/subtract routine only handles non-negative results\r
- so we may need to swap the operands. */\r
- {do{/*select*/\r
- if (rhs.ind==iszero){\r
- // original A bigger\r
- }else if ((usellen<userlen)|(lhs.ind==iszero))\r
- { // original B bigger\r
- t=usel;\r
- usel=user;\r
- user=t; // swap\r
- tlen=usellen;\r
- usellen=userlen;\r
- userlen=tlen; // ..\r
- res.ind=(byte)-res.ind; // and set sign\r
- }\r
- else if (usellen>userlen){\r
- // original A bigger\r
- }else{\r
- {/* logical lengths the same */ // need compare\r
- /* may still need to swap: compare the strings */\r
- ia=0;\r
- ib=0;\r
- ea=usel.length-1;\r
- eb=user.length-1;\r
- {compare:for(;;){\r
- if (ia<=ea) \r
- ca=usel[ia];\r
- else \r
- {\r
- if (ib>eb) \r
- {/* identical */\r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN) \r
- return ZERO;\r
- // [if PLAIN we must do the subtract, in case of 0.000 results]\r
- break compare;\r
- }\r
- ca=(byte)0;\r
- }\r
- if (ib<=eb) \r
- cb=user[ib];\r
- else \r
- cb=(byte)0;\r
- if (ca!=cb) \r
- {\r
- if (ca<cb) \r
- {/* swap needed */\r
- t=usel;\r
- usel=user;\r
- user=t; // swap\r
- tlen=usellen;\r
- usellen=userlen;\r
- userlen=tlen; // ..\r
- res.ind=(byte)-res.ind;\r
- }\r
- break compare;\r
- }\r
- /* mantissas the same, so far */\r
- ia++;\r
- ib++;\r
- }\r
- }/*compare*/\r
- } // lengths the same\r
- }\r
- }while(false);}/*swaptest*/\r
- }while(false);}/*signdiff*/\r
- \r
- /* here, A is > B if subtracting */\r
- // add [A+B*1] or subtract [A+(B*-1)]\r
- res.mant=byteaddsub(usel,usellen,user,userlen,mult,false);\r
- // [reuse possible only after chop; accounting makes not worthwhile]\r
- \r
- // Finish() rounds before stripping leading 0's, then sets form, etc.\r
- return res.finish(set,false);\r
- }\r
-\r
- /**\r
- * Compares this <code>BigDecimal</code> to another, using unlimited\r
- * precision.\r
- * <p>\r
- * The same as {@link #compareTo(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @return An <code>int</code> whose value is -1, 0, or 1 as\r
- * <code>this</code> is numerically less than, equal to,\r
- * or greater than <code>rhs</code>.\r
- * @see #compareTo(Object)\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int compareTo(com.ibm.icu.math.BigDecimal rhs){\r
- return this.compareTo(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Compares this <code>BigDecimal</code> to another.\r
- * <p>\r
- * Implements numeric comparison,\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns a result of type <code>int</code>.\r
- * <p>\r
- * The result will be:\r
- * <table cellpadding=2><tr>\r
- * <td align=right><b>-1</b></td>\r
- * <td>if the current object is less than the first parameter</td>\r
- * </tr><tr>\r
- * <td align=right><b>0</b></td>\r
- * <td>if the current object is equal to the first parameter</td>\r
- * </tr><tr>\r
- * <td align=right><b>1</b></td>\r
- * <td>if the current object is greater than the first parameter.</td>\r
- * </tr></table>\r
- * <p>\r
- * A {@link #compareTo(Object)} method is also provided.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return An <code>int</code> whose value is -1, 0, or 1 as\r
- * <code>this</code> is numerically less than, equal to,\r
- * or greater than <code>rhs</code>.\r
- * @see #compareTo(Object)\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int compareTo(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- int thislength=0;\r
- int i=0;\r
- com.ibm.icu.math.BigDecimal newrhs;\r
- // rhs=null will raise NullPointerException, as per Comparable interface\r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- // [add will recheck in slowpath cases .. but would report -rhs]\r
- if ((this.ind==rhs.ind)&(this.exp==rhs.exp)) \r
- {\r
- /* sign & exponent the same [very common] */\r
- thislength=this.mant.length;\r
- if (thislength<rhs.mant.length) \r
- return (byte)-this.ind;\r
- if (thislength>rhs.mant.length) \r
- return this.ind;\r
- /* lengths are the same; we can do a straight mantissa compare\r
- unless maybe rounding [rounding is very unusual] */\r
- if ((thislength<=set.digits)|(set.digits==0)) \r
- {\r
- {int $6=thislength;i=0;for(;$6>0;$6--,i++){\r
- if (this.mant[i]<rhs.mant[i]) \r
- return (byte)-this.ind;\r
- if (this.mant[i]>rhs.mant[i]) \r
- return this.ind;\r
- }\r
- }/*i*/\r
- return 0; // identical\r
- }\r
- /* drop through for full comparison */\r
- }\r
- else \r
- {\r
- /* More fastpaths possible */\r
- if (this.ind<rhs.ind) \r
- return -1;\r
- if (this.ind>rhs.ind) \r
- return 1;\r
- }\r
- /* carry out a subtract to make the comparison */\r
- newrhs=clone(rhs); // safe copy\r
- newrhs.ind=(byte)-newrhs.ind; // prepare to subtract\r
- return this.add(newrhs,set).ind; // add, and return sign of result\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #divide(BigDecimal, int)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the rounding mode is {@link MathContext#ROUND_HALF_UP}.\r
- *\r
- * The length of the decimal part (the scale) of the result will be\r
- * the same as the scale of the current object, if the latter were\r
- * formatted without exponential notation.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the division.\r
- * @return A plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs){\r
- return this.dodivide('D',rhs,plainMC,-1);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic and a\r
- * rounding mode.\r
- * <p>\r
- * The same as {@link #divide(BigDecimal, int, int)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the second parameter is <code>this.scale()</code>, and\r
- * the third is <code>round</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will\r
- * therefore be the same as the scale of the current object, if the\r
- * latter were formatted without exponential notation.\r
- * <p>\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the division.\r
- * @param round The <code>int</code> rounding mode to be used for\r
- * the division (see the {@link MathContext} class).\r
- * @return A plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic\r
- * and the specified rounding mode.\r
- * @throws IllegalArgumentException if <code>round</code> is not a\r
- * valid rounding mode.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @throws ArithmeticException if <code>round</code> is {@link\r
- * MathContext#ROUND_UNNECESSARY} and\r
- * <code>this.scale()</code> is insufficient to\r
- * represent the result exactly.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,int round){\r
- com.ibm.icu.math.MathContext set;\r
- set=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN,false,round); // [checks round, too]\r
- return this.dodivide('D',rhs,set,-1); // take scale from LHS\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic and a\r
- * given scale and rounding mode.\r
- * <p>\r
- * The same as {@link #divide(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>,\r
- * except that the length of the decimal part (the scale) to be used\r
- * for the result is explicit rather than being taken from\r
- * <code>this</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * the same as the scale of the current object, if the latter were\r
- * formatted without exponential notation.\r
- * <p>\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the division.\r
- * @param scale The <code>int</code> scale to be used for the result.\r
- * @param round The <code>int</code> rounding mode to be used for\r
- * the division (see the {@link MathContext} class).\r
- * @return A plain <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>, using fixed point arithmetic\r
- * and the specified rounding mode.\r
- * @throws IllegalArgumentException if <code>round</code> is not a\r
- * valid rounding mode.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @throws ArithmeticException if <code>scale</code> is negative.\r
- * @throws ArithmeticException if <code>round</code> is {@link\r
- * MathContext#ROUND_UNNECESSARY} and <code>scale</code>\r
- * is insufficient to represent the result exactly.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,int scale,int round){\r
- com.ibm.icu.math.MathContext set;\r
- if (scale<0) \r
- throw new java.lang.ArithmeticException("Negative scale:"+" "+scale);\r
- set=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN,false,round); // [checks round]\r
- return this.dodivide('D',rhs,set,scale);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.\r
- * <p>\r
- * Implements the division (<b><code>/</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the division.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this/rhs</code>.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- return this.dodivide('D',rhs,set,-1);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is the integer\r
- * part of <code>this/rhs</code>.\r
- * <p>\r
- * The same as {@link #divideInteger(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the integer division.\r
- * @return A <code>BigDecimal</code> whose value is the integer\r
- * part of <code>this/rhs</code>.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs){\r
- // scale 0 to drop .000 when plain\r
- return this.dodivide('I',rhs,plainMC,0);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is the integer\r
- * part of <code>this/rhs</code>.\r
- * <p>\r
- * Implements the integer division operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the integer division.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is the integer\r
- * part of <code>this/rhs</code>.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @throws ArithmeticException if the result will not fit in the\r
- * number of digits specified for the context.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- // scale 0 to drop .000 when plain\r
- return this.dodivide('I',rhs,set,0);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * the maximum of <code>this</code> and <code>rhs</code>.\r
- * <p>\r
- * The same as {@link #max(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * the maximum of <code>this</code> and <code>rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs){\r
- return this.max(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is\r
- * the maximum of <code>this</code> and <code>rhs</code>.\r
- * <p>\r
- * Returns the larger of the current object and the first parameter.\r
- * <p>\r
- * If calling the {@link #compareTo(BigDecimal, MathContext)} method\r
- * with the same parameters would return <code>1</code> or\r
- * <code>0</code>, then the result of calling the\r
- * {@link #plus(MathContext)} method on the current object (using the\r
- * same <code>MathContext</code> parameter) is returned.\r
- * Otherwise, the result of calling the {@link #plus(MathContext)}\r
- * method on the first parameter object (using the same\r
- * <code>MathContext</code> parameter) is returned.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * the maximum of <code>this</code> and <code>rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- if ((this.compareTo(rhs,set))>=0) \r
- return this.plus(set);\r
- else \r
- return rhs.plus(set);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * the minimum of <code>this</code> and <code>rhs</code>.\r
- * <p>\r
- * The same as {@link #min(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * the minimum of <code>this</code> and <code>rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs){\r
- return this.min(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is\r
- * the minimum of <code>this</code> and <code>rhs</code>.\r
- * <p>\r
- * Returns the smaller of the current object and the first parameter.\r
- * <p>\r
- * If calling the {@link #compareTo(BigDecimal, MathContext)} method\r
- * with the same parameters would return <code>-1</code> or\r
- * <code>0</code>, then the result of calling the\r
- * {@link #plus(MathContext)} method on the current object (using the\r
- * same <code>MathContext</code> parameter) is returned.\r
- * Otherwise, the result of calling the {@link #plus(MathContext)}\r
- * method on the first parameter object (using the same\r
- * <code>MathContext</code> parameter) is returned.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the comparison.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * the minimum of <code>this</code> and <code>rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- if ((this.compareTo(rhs,set))<=0) \r
- return this.plus(set);\r
- else \r
- return rhs.plus(set);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this*rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #add(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * the sum of the scales of the operands, if they were formatted\r
- * without exponential notation.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the multiplication.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this*rhs</code>, using fixed point arithmetic.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs){\r
- return this.multiply(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.\r
- * <p>\r
- * Implements the multiplication (<b><code>*</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the multiplication.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this*rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- com.ibm.icu.math.BigDecimal lhs;\r
- int padding;\r
- int reqdig;\r
- byte multer[]=null;\r
- byte multand[]=null;\r
- int multandlen;\r
- int acclen=0;\r
- com.ibm.icu.math.BigDecimal res;\r
- byte acc[];\r
- int n=0;\r
- byte mult=0;\r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- lhs=this; // name for clarity and proxy\r
- \r
- /* Prepare numbers (truncate, unless unlimited precision) */\r
- padding=0; // trailing 0's to add\r
- reqdig=set.digits; // local copy\r
- if (reqdig>0) \r
- {\r
- if (lhs.mant.length>reqdig) \r
- lhs=clone(lhs).round(set);\r
- if (rhs.mant.length>reqdig) \r
- rhs=clone(rhs).round(set);\r
- // [we could reuse the new LHS for result in this case]\r
- }\r
- else \r
- {/* unlimited */\r
- // fixed point arithmetic will want every trailing 0; we add these\r
- // after the calculation rather than before, for speed.\r
- if (lhs.exp>0) \r
- padding=padding+lhs.exp;\r
- if (rhs.exp>0) \r
- padding=padding+rhs.exp;\r
- }\r
- \r
- // For best speed, as in DMSRCN, we use the shorter number as the\r
- // multiplier and the longer as the multiplicand.\r
- // 1999.12.22: We used to special case when the result would fit in\r
- // a long, but with Java 1.3 this gave no advantage.\r
- if (lhs.mant.length<rhs.mant.length) \r
- {\r
- multer=lhs.mant;\r
- multand=rhs.mant;\r
- }\r
- else \r
- {\r
- multer=rhs.mant;\r
- multand=lhs.mant;\r
- }\r
- \r
- /* Calculate how long result byte array will be */\r
- multandlen=(multer.length+multand.length)-1; // effective length\r
- // optimize for 75% of the cases where a carry is expected...\r
- if ((multer[0]*multand[0])>9) \r
- acclen=multandlen+1;\r
- else \r
- acclen=multandlen;\r
- \r
- /* Now the main long multiplication loop */\r
- res=new com.ibm.icu.math.BigDecimal(); // where we'll build result\r
- acc=new byte[acclen]; // accumulator, all zeros\r
- // 1998.07.01: calculate from left to right so that accumulator goes\r
- // to likely final length on first addition; this avoids a one-digit\r
- // extension (and object allocation) each time around the loop.\r
- // Initial number therefore has virtual zeros added to right.\r
- {int $7=multer.length;n=0;for(;$7>0;$7--,n++){\r
- mult=multer[n];\r
- if (mult!=0) \r
- { // [optimization]\r
- // accumulate [accumulator is reusable array]\r
- acc=byteaddsub(acc,acc.length,multand,multandlen,mult,true);\r
- }\r
- // divide multiplicand by 10 for next digit to right\r
- multandlen--; // 'virtual length'\r
- }\r
- }/*n*/\r
- \r
- res.ind=(byte)(lhs.ind*rhs.ind); // final sign\r
- res.exp=(lhs.exp+rhs.exp)-padding; // final exponent\r
- // [overflow is checked by finish]\r
- \r
- /* add trailing zeros to the result, if necessary */\r
- if (padding==0) \r
- res.mant=acc;\r
- else \r
- res.mant=extend(acc,acc.length+padding); // add trailing 0s\r
- return res.finish(set,false);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>-this</code>.\r
- * <p>\r
- * The same as {@link #negate(MathContext)}, where the context is\r
- * <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * be <code>this.scale()</code>\r
- *\r
- *\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>-this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal negate(){\r
- return this.negate(plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.\r
- * <p>\r
- * Implements the negation (Prefix <b><code>-</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>-this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set){\r
- com.ibm.icu.math.BigDecimal res;\r
- // Originally called minus(), changed to matched Java precedents\r
- // This simply clones, flips the sign, and possibly rounds\r
- if (set.lostDigits) \r
- checkdigits((com.ibm.icu.math.BigDecimal)null,set.digits);\r
- res=clone(this); // safe copy\r
- res.ind=(byte)-res.ind;\r
- return res.finish(set,false);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>+this</code>.\r
- * Note that <code>this</code> is not necessarily a\r
- * plain <code>BigDecimal</code>, but the result will always be.\r
- * <p>\r
- * The same as {@link #plus(MathContext)}, where the context is\r
- * <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * be <code>this.scale()</code>\r
- *\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>+this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal plus(){\r
- return this.plus(plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is\r
- * <code>+this</code>.\r
- * <p>\r
- * Implements the plus (Prefix <b><code>+</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- * <p>\r
- * This method is useful for rounding or otherwise applying a context\r
- * to a decimal value.\r
- *\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>+this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set){\r
- // This clones and forces the result to the new settings\r
- // May return same object\r
- if (set.lostDigits) \r
- checkdigits((com.ibm.icu.math.BigDecimal)null,set.digits);\r
- // Optimization: returns same object for some common cases\r
- if (set.form==com.ibm.icu.math.MathContext.PLAIN) \r
- if (this.form==com.ibm.icu.math.MathContext.PLAIN) \r
- {\r
- if (this.mant.length<=set.digits) \r
- return this;\r
- if (set.digits==0) \r
- return this;\r
- }\r
- return clone(this).finish(set,false);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this**rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #pow(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The parameter is the power to which the <code>this</code> will be\r
- * raised; it must be in the range 0 through 999999999, and must\r
- * have a decimal part of zero. Note that these restrictions may be\r
- * removed in the future, so they should not be used as a test for a\r
- * whole number.\r
- * <p>\r
- * In addition, the power must not be negative, as no\r
- * <code>MathContext</code> is used and so the result would then\r
- * always be 0.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the operation (the power).\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this**rhs</code>, using fixed point arithmetic.\r
- * @throws ArithmeticException if <code>rhs</code> is out of range or\r
- * is not a whole number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs){\r
- return this.pow(rhs,plainMC);\r
- }\r
- // The name for this method is inherited from the precedent set by the\r
- // BigInteger and Math classes.\r
- \r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.\r
- * <p>\r
- * Implements the power (<b><code>**</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- * <p>\r
- * The first parameter is the power to which the <code>this</code>\r
- * will be raised; it must be in the range -999999999 through\r
- * 999999999, and must have a decimal part of zero. Note that these\r
- * restrictions may be removed in the future, so they should not be\r
- * used as a test for a whole number.\r
- * <p>\r
- * If the <code>digits</code> setting of the <code>MathContext</code>\r
- * parameter is 0, the power must be zero or positive.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the operation (the power).\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this**rhs</code>.\r
- * @throws ArithmeticException if <code>rhs</code> is out of range or\r
- * is not a whole number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- int n;\r
- com.ibm.icu.math.BigDecimal lhs;\r
- int reqdig;\r
- int workdigits=0;\r
- int L=0;\r
- com.ibm.icu.math.MathContext workset;\r
- com.ibm.icu.math.BigDecimal res;\r
- boolean seenbit;\r
- int i=0;\r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- n=rhs.intcheck(MinArg,MaxArg); // check RHS by the rules\r
- lhs=this; // clarified name\r
- \r
- reqdig=set.digits; // local copy (heavily used)\r
- if (reqdig==0) \r
- {\r
- if (rhs.ind==isneg) \r
- throw new java.lang.ArithmeticException("Negative power:"+" "+rhs.toString());\r
- workdigits=0;\r
- }\r
- else \r
- {/* non-0 digits */\r
- if ((rhs.mant.length+rhs.exp)>reqdig) \r
- throw new java.lang.ArithmeticException("Too many digits:"+" "+rhs.toString());\r
- \r
- /* Round the lhs to DIGITS if need be */\r
- if (lhs.mant.length>reqdig) \r
- lhs=clone(lhs).round(set);\r
- \r
- /* L for precision calculation [see ANSI X3.274-1996] */\r
- L=rhs.mant.length+rhs.exp; // length without decimal zeros/exp\r
- workdigits=(reqdig+L)+1; // calculate the working DIGITS\r
- }\r
- \r
- /* Create a copy of set for working settings */\r
- // Note: no need to check for lostDigits again.\r
- // 1999.07.17 Note: this construction must follow RHS check\r
- workset=new com.ibm.icu.math.MathContext(workdigits,set.form,false,set.roundingMode);\r
- \r
- res=ONE; // accumulator\r
- if (n==0) \r
- return res; // x**0 == 1\r
- if (n<0) \r
- n=(int)-n; // [rhs.ind records the sign]\r
- seenbit=false; // set once we've seen a 1-bit\r
- {i=1;i:for(;;i++){ // for each bit [top bit ignored]\r
- n=n+n; // shift left 1 bit\r
- if (n<0) \r
- { // top bit is set\r
- seenbit=true; // OK, we're off\r
- res=res.multiply(lhs,workset); // acc=acc*x\r
- }\r
- if (i==31) \r
- break i; // that was the last bit\r
- if ((!seenbit)) \r
- continue i; // we don't have to square 1\r
- res=res.multiply(res,workset); // acc=acc*acc [square]\r
- }\r
- }/*i*/ // 32 bits\r
- if (rhs.ind<0) // was a **-n [hence digits>0]\r
- res=ONE.divide(res,workset); // .. so acc=1/acc\r
- return res.finish(set,true); // round and strip [original digits]\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * the remainder of <code>this/rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #remainder(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * This is not the modulo operator -- the result may be negative.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the remainder operation.\r
- * @return A <code>BigDecimal</code> whose value is the remainder\r
- * of <code>this/rhs</code>, using fixed point arithmetic.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs){\r
- return this.dodivide('R',rhs,plainMC,-1);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is the remainder of\r
- * <code>this/rhs</code>.\r
- * <p>\r
- * Implements the remainder operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- * <p>\r
- * This is not the modulo operator -- the result may be negative.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the remainder operation.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is the remainder\r
- * of <code>this+rhs</code>.\r
- * @throws ArithmeticException if <code>rhs</code> is zero.\r
- * @throws ArithmeticException if the integer part of the result will\r
- * not fit in the number of digits specified for the\r
- * context.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- return this.dodivide('R',rhs,set,-1);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose value is\r
- * <code>this-rhs</code>, using fixed point arithmetic.\r
- * <p>\r
- * The same as {@link #subtract(BigDecimal, MathContext)},\r
- * where the <code>BigDecimal</code> is <code>rhs</code>,\r
- * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.\r
- * <p>\r
- * The length of the decimal part (the scale) of the result will be\r
- * the maximum of the scales of the two operands.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the subtraction.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this-rhs</code>, using fixed point arithmetic.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs){\r
- return this.subtract(rhs,plainMC);\r
- }\r
-\r
- /**\r
- * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.\r
- * <p>\r
- * Implements the subtraction (<b><code>-</code></b>) operator\r
- * (as defined in the decimal documentation, see {@link BigDecimal\r
- * class header}),\r
- * and returns the result as a <code>BigDecimal</code> object.\r
- *\r
- * @param rhs The <code>BigDecimal</code> for the right hand side of\r
- * the subtraction.\r
- * @param set The <code>MathContext</code> arithmetic settings.\r
- * @return A <code>BigDecimal</code> whose value is\r
- * <code>this-rhs</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){\r
- com.ibm.icu.math.BigDecimal newrhs;\r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- // [add will recheck .. but would report -rhs]\r
- /* carry out the subtraction */\r
- // we could fastpath -0, but it is too rare.\r
- newrhs=clone(rhs); // safe copy\r
- newrhs.ind=(byte)-newrhs.ind; // prepare to subtract\r
- return this.add(newrhs,set); // arithmetic\r
- }\r
-\r
- /* ---------------------------------------------------------------- */\r
- /* Other methods */\r
- /* ---------------------------------------------------------------- */\r
- \r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>byte</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part or is\r
- * out of the possible range for a <code>byte</code> (8-bit signed\r
- * integer) result then an <code>ArithmeticException</code> is thrown.\r
- *\r
- * @return A <code>byte</code> equal in value to <code>this</code>.\r
- * @throws ArithmeticException if <code>this</code> has a non-zero\r
- * decimal part, or will not fit in a <code>byte</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public byte byteValueExact(){\r
- int num;\r
- num=this.intValueExact(); // will check decimal part too\r
- if ((num>127)|(num<(-128))) \r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- return (byte)num;\r
- }\r
-\r
- /**\r
- * Compares this <code>BigDecimal</code> with the value of the parameter.\r
- * <p>\r
- * If the parameter is <code>null</code>, or is not an instance of the\r
- * <code>BigDecimal</code> type, an exception is thrown.\r
- * Otherwise, the parameter is cast to type <code>BigDecimal</code>\r
- * and the result of the {@link #compareTo(BigDecimal)} method,\r
- * using the cast parameter, is returned.\r
- * <p>\r
- * The {@link #compareTo(BigDecimal, MathContext)} method should be\r
- * used when a <code>MathContext</code> is needed for the comparison.\r
- *\r
- * @param rhsobj The <code>Object</code> for the right hand side of\r
- * the comparison.\r
- * @return An <code>int</code> whose value is -1, 0, or 1 as\r
- * <code>this</code> is numerically less than, equal to,\r
- * or greater than <code>rhs</code>.\r
- * @throws ClassCastException if <code>rhs</code> cannot be cast to\r
- * a <code>BigDecimal</code> object.\r
- * @see #compareTo(BigDecimal)\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int compareTo(java.lang.Object rhsobj){\r
- // the cast in the next line will raise ClassCastException if necessary\r
- return compareTo((com.ibm.icu.math.BigDecimal)rhsobj,plainMC);\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>double</code>.\r
- * If the <code>BigDecimal</code> is out of the possible range for a\r
- * <code>double</code> (64-bit signed floating point) result then an\r
- * <code>ArithmeticException</code> is thrown.\r
- * <p>\r
- * The double produced is identical to result of expressing the\r
- * <code>BigDecimal</code> as a <code>String</code> and then\r
- * converting it using the <code>Double(String)</code> constructor;\r
- * this can result in values of <code>Double.NEGATIVE_INFINITY</code>\r
- * or <code>Double.POSITIVE_INFINITY</code>.\r
- *\r
- * @return A <code>double</code> corresponding to <code>this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public double doubleValue(){\r
- // We go via a String [as does BigDecimal in JDK 1.2]\r
- // Next line could possibly raise NumberFormatException\r
- return java.lang.Double.valueOf(this.toString()).doubleValue();\r
- }\r
-\r
- /**\r
- * Compares this <code>BigDecimal</code> with <code>rhs</code> for\r
- * equality.\r
- * <p>\r
- * If the parameter is <code>null</code>, or is not an instance of the\r
- * BigDecimal type, or is not exactly equal to the current\r
- * <code>BigDecimal</code> object, then <i>false</i> is returned.\r
- * Otherwise, <i>true</i> is returned.\r
- * <p>\r
- * "Exactly equal", here, means that the <code>String</code>\r
- * representations of the <code>BigDecimal</code> numbers are\r
- * identical (they have the same characters in the same sequence).\r
- * <p>\r
- * The {@link #compareTo(BigDecimal, MathContext)} method should be\r
- * used for more general comparisons.\r
- * @param obj The <code>Object</code> for the right hand side of\r
- * the comparison.\r
- * @return A <code>boolean</code> whose value <i>true</i> if and\r
- * only if the operands have identical string representations.\r
- * @throws ClassCastException if <code>rhs</code> cannot be cast to\r
- * a <code>BigDecimal</code> object.\r
- * @stable ICU 2.0\r
- * @see #compareTo(Object)\r
- * @see #compareTo(BigDecimal)\r
- * @see #compareTo(BigDecimal, MathContext)\r
- */\r
- \r
- public boolean equals(java.lang.Object obj){\r
- com.ibm.icu.math.BigDecimal rhs;\r
- int i=0;\r
- char lca[]=null;\r
- char rca[]=null;\r
- // We are equal iff toString of both are exactly the same\r
- if (obj==null) \r
- return false; // not equal\r
- if ((!(((obj instanceof com.ibm.icu.math.BigDecimal))))) \r
- return false; // not a decimal\r
- rhs=(com.ibm.icu.math.BigDecimal)obj; // cast; we know it will work\r
- if (this.ind!=rhs.ind) \r
- return false; // different signs never match\r
- if (((this.mant.length==rhs.mant.length)&(this.exp==rhs.exp))&(this.form==rhs.form)) \r
- \r
- { // mantissas say all\r
- // here with equal-length byte arrays to compare\r
- {int $8=this.mant.length;i=0;for(;$8>0;$8--,i++){\r
- if (this.mant[i]!=rhs.mant[i]) \r
- return false;\r
- }\r
- }/*i*/\r
- }\r
- else \r
- { // need proper layout\r
- lca=this.layout(); // layout to character array\r
- rca=rhs.layout();\r
- if (lca.length!=rca.length) \r
- return false; // mismatch\r
- // here with equal-length character arrays to compare\r
- {int $9=lca.length;i=0;for(;$9>0;$9--,i++){\r
- if (lca[i]!=rca[i]) \r
- return false;\r
- }\r
- }/*i*/\r
- }\r
- return true; // arrays have identical content\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>float</code>.\r
- * If the <code>BigDecimal</code> is out of the possible range for a\r
- * <code>float</code> (32-bit signed floating point) result then an\r
- * <code>ArithmeticException</code> is thrown.\r
- * <p>\r
- * The float produced is identical to result of expressing the\r
- * <code>BigDecimal</code> as a <code>String</code> and then\r
- * converting it using the <code>Float(String)</code> constructor;\r
- * this can result in values of <code>Float.NEGATIVE_INFINITY</code>\r
- * or <code>Float.POSITIVE_INFINITY</code>.\r
- *\r
- * @return A <code>float</code> corresponding to <code>this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public float floatValue(){\r
- return java.lang.Float.valueOf(this.toString()).floatValue();\r
- }\r
-\r
- /**\r
- * Returns the <code>String</code> representation of this\r
- * <code>BigDecimal</code>, modified by layout parameters.\r
- * <p>\r
- * <i>This method is provided as a primitive for use by more\r
- * sophisticated classes, such as <code>DecimalFormat</code>, that\r
- * can apply locale-sensitive editing of the result. The level of\r
- * formatting that it provides is a necessary part of the BigDecimal\r
- * class as it is sensitive to and must follow the calculation and\r
- * rounding rules for BigDecimal arithmetic.\r
- * However, if the function is provided elsewhere, it may be removed\r
- * from this class. </i>\r
- * <p>\r
- * The parameters, for both forms of the <code>format</code> method\r
- * are all of type <code>int</code>.\r
- * A value of -1 for any parameter indicates that the default action\r
- * or value for that parameter should be used.\r
- * <p>\r
- * The parameters, <code>before</code> and <code>after</code>,\r
- * specify the number of characters to be used for the integer part\r
- * and decimal part of the result respectively. Exponential notation\r
- * is not used. If either parameter is -1 (which indicates the default\r
- * action), the number of characters used will be exactly as many as\r
- * are needed for that part.\r
- * <p>\r
- * <code>before</code> must be a positive number; if it is larger than\r
- * is needed to contain the integer part, that part is padded on the\r
- * left with blanks to the requested length. If <code>before</code> is\r
- * not large enough to contain the integer part of the number\r
- * (including the sign, for negative numbers) an exception is thrown.\r
- * <p>\r
- * <code>after</code> must be a non-negative number; if it is not the\r
- * same size as the decimal part of the number, the number will be\r
- * rounded (or extended with zeros) to fit. Specifying 0 for\r
- * <code>after</code> will cause the number to be rounded to an\r
- * integer (that is, it will have no decimal part or decimal point).\r
- * The rounding method will be the default,\r
- * <code>MathContext.ROUND_HALF_UP</code>.\r
- * <p>\r
- * Other rounding methods, and the use of exponential notation, can\r
- * be selected by using {@link #format(int,int,int,int,int,int)}.\r
- * Using the two-parameter form of the method has exactly the same\r
- * effect as using the six-parameter form with the final four\r
- * parameters all being -1.\r
- *\r
- * @param before The <code>int</code> specifying the number of places\r
- * before the decimal point. Use -1 for 'as many as\r
- * are needed'.\r
- * @param after The <code>int</code> specifying the number of places\r
- * after the decimal point. Use -1 for 'as many as are\r
- * needed'.\r
- * @return A <code>String</code> representing this\r
- * <code>BigDecimal</code>, laid out according to the\r
- * specified parameters\r
- * @throws ArithmeticException if the number cannot be laid out as\r
- * requested.\r
- * @throws IllegalArgumentException if a parameter is out of range.\r
- * @stable ICU 2.0\r
- * @see #toString\r
- * @see #toCharArray\r
- */\r
- \r
- public java.lang.String format(int before,int after){\r
- return format(before,after,-1,-1,com.ibm.icu.math.MathContext.SCIENTIFIC,ROUND_HALF_UP);\r
- }\r
-\r
- /**\r
- * Returns the <code>String</code> representation of this\r
- * <code>BigDecimal</code>, modified by layout parameters and allowing\r
- * exponential notation.\r
- * <p>\r
- * <i>This method is provided as a primitive for use by more\r
- * sophisticated classes, such as <code>DecimalFormat</code>, that\r
- * can apply locale-sensitive editing of the result. The level of\r
- * formatting that it provides is a necessary part of the BigDecimal\r
- * class as it is sensitive to and must follow the calculation and\r
- * rounding rules for BigDecimal arithmetic.\r
- * However, if the function is provided elsewhere, it may be removed\r
- * from this class. </i>\r
- * <p>\r
- * The parameters are all of type <code>int</code>.\r
- * A value of -1 for any parameter indicates that the default action\r
- * or value for that parameter should be used.\r
- * <p>\r
- * The first two parameters (<code>before</code> and\r
- * <code>after</code>) specify the number of characters to be used for\r
- * the integer part and decimal part of the result respectively, as\r
- * defined for {@link #format(int,int)}.\r
- * If either of these is -1 (which indicates the default action), the\r
- * number of characters used will be exactly as many as are needed for\r
- * that part.\r
- * <p>\r
- * The remaining parameters control the use of exponential notation\r
- * and rounding. Three (<code>explaces</code>, <code>exdigits</code>,\r
- * and <code>exform</code>) control the exponent part of the result.\r
- * As before, the default action for any of these parameters may be\r
- * selected by using the value -1.\r
- * <p>\r
- * <code>explaces</code> must be a positive number; it sets the number\r
- * of places (digits after the sign of the exponent) to be used for\r
- * any exponent part, the default (when <code>explaces</code> is -1)\r
- * being to use as many as are needed.\r
- * If <code>explaces</code> is not -1, space is always reserved for\r
- * an exponent; if one is not needed (for example, if the exponent\r
- * will be 0) then <code>explaces</code>+2 blanks are appended to the\r
- * result.\r
- * <!-- (This preserves vertical alignment of similarly formatted\r
- * numbers in a monospace font.) -->\r
- * If <code>explaces</code> is not -1 and is not large enough to\r
- * contain the exponent, an exception is thrown.\r
- * <p>\r
- * <code>exdigits</code> sets the trigger point for use of exponential\r
- * notation. If, before any rounding, the number of places needed\r
- * before the decimal point exceeds <code>exdigits</code>, or if the\r
- * absolute value of the result is less than <code>0.000001</code>,\r
- * then exponential form will be used, provided that\r
- * <code>exdigits</code> was specified.\r
- * When <code>exdigits</code> is -1, exponential notation will never\r
- * be used. If 0 is specified for <code>exdigits</code>, exponential\r
- * notation is always used unless the exponent would be 0.\r
- * <p>\r
- * <code>exform</code> sets the form for exponential notation (if\r
- * needed).\r
- * It may be either {@link MathContext#SCIENTIFIC} or\r
- * {@link MathContext#ENGINEERING}.\r
- * If the latter, engineering, form is requested, up to three digits\r
- * (plus sign, if negative) may be needed for the integer part of the\r
- * result (<code>before</code>). Otherwise, only one digit (plus\r
- * sign, if negative) is needed.\r
- * <p>\r
- * Finally, the sixth argument, <code>exround</code>, selects the\r
- * rounding algorithm to be used, and must be one of the values\r
- * indicated by a public constant in the {@link MathContext} class\r
- * whose name starts with <code>ROUND_</code>.\r
- * The default (<code>ROUND_HALF_UP</code>) may also be selected by\r
- * using the value -1, as before.\r
- * <p>\r
- * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be\r
- * used to detect whether non-zero digits are discarded -- if\r
- * <code>exround</code> has this value than if non-zero digits would\r
- * be discarded (rounded) during formatting then an\r
- * <code>ArithmeticException</code> is thrown.\r
- *\r
- * @param before The <code>int</code> specifying the number of places\r
- * before the decimal point.\r
- * Use -1 for 'as many as are needed'.\r
- * @param after The <code>int</code> specifying the number of places\r
- * after the decimal point.\r
- * Use -1 for 'as many as are needed'.\r
- * @param explaces The <code>int</code> specifying the number of places\r
- * to be used for any exponent.\r
- * Use -1 for 'as many as are needed'.\r
- * @param exdigits The <code>int</code> specifying the trigger\r
- * (digits before the decimal point) which if\r
- * exceeded causes exponential notation to be used.\r
- * Use 0 to force exponential notation.\r
- * Use -1 to force plain notation (no exponential\r
- * notation).\r
- * @param exformint The <code>int</code> specifying the form of\r
- * exponential notation to be used\r
- * ({@link MathContext#SCIENTIFIC} or\r
- * {@link MathContext#ENGINEERING}).\r
- * @param exround The <code>int</code> specifying the rounding mode\r
- * to use.\r
- * Use -1 for the default, {@link MathContext#ROUND_HALF_UP}.\r
- * @return A <code>String</code> representing this\r
- * <code>BigDecimal</code>, laid out according to the\r
- * specified parameters\r
- * @throws ArithmeticException if the number cannot be laid out as\r
- * requested.\r
- * @throws IllegalArgumentException if a parameter is out of range.\r
- * @see #toString\r
- * @see #toCharArray\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.lang.String format(int before,int after,int explaces,int exdigits,int exformint,int exround){\r
- com.ibm.icu.math.BigDecimal num;\r
- int mag=0;\r
- int thisafter=0;\r
- int lead=0;\r
- byte newmant[]=null;\r
- int chop=0;\r
- int need=0;\r
- int oldexp=0;\r
- char a[];\r
- int p=0;\r
- char newa[]=null;\r
- int i=0;\r
- int places=0;\r
- \r
- \r
- /* Check arguments */\r
- if ((before<(-1))|(before==0)) \r
- badarg("format",1,java.lang.String.valueOf(before));\r
- if (after<(-1)) \r
- badarg("format",2,java.lang.String.valueOf(after));\r
- if ((explaces<(-1))|(explaces==0)) \r
- badarg("format",3,java.lang.String.valueOf(explaces));\r
- if (exdigits<(-1)) \r
- badarg("format",4,java.lang.String.valueOf(explaces));\r
- {/*select*/\r
- if (exformint==com.ibm.icu.math.MathContext.SCIENTIFIC){\r
- }else if (exformint==com.ibm.icu.math.MathContext.ENGINEERING){\r
- }else if (exformint==(-1))\r
- exformint=com.ibm.icu.math.MathContext.SCIENTIFIC;\r
- // note PLAIN isn't allowed\r
- else{\r
- badarg("format",5,java.lang.String.valueOf(exformint));\r
- }\r
- }\r
- // checking the rounding mode is done by trying to construct a\r
- // MathContext object with that mode; it will fail if bad\r
- if (exround!=ROUND_HALF_UP) \r
- {try{ // if non-default...\r
- if (exround==(-1)) \r
- exround=ROUND_HALF_UP;\r
- else \r
- new com.ibm.icu.math.MathContext(9,com.ibm.icu.math.MathContext.SCIENTIFIC,false,exround);\r
- }\r
- catch (java.lang.IllegalArgumentException $10){\r
- badarg("format",6,java.lang.String.valueOf(exround));\r
- }}\r
- \r
- num=clone(this); // make private copy\r
- \r
- /* Here:\r
- num is BigDecimal to format\r
- before is places before point [>0]\r
- after is places after point [>=0]\r
- explaces is exponent places [>0]\r
- exdigits is exponent digits [>=0]\r
- exformint is exponent form [one of two]\r
- exround is rounding mode [one of eight]\r
- 'before' through 'exdigits' are -1 if not specified\r
- */\r
- \r
- /* determine form */\r
- {do{/*select*/\r
- if (exdigits==(-1))\r
- num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;\r
- else if (num.ind==iszero)\r
- num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;\r
- else{\r
- // determine whether triggers\r
- mag=num.exp+num.mant.length;\r
- if (mag>exdigits) \r
- num.form=(byte)exformint;\r
- else \r
- if (mag<(-5)) \r
- num.form=(byte)exformint;\r
- else \r
- num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;\r
- }\r
- }while(false);}/*setform*/\r
- \r
- /* If 'after' was specified then we may need to adjust the\r
- mantissa. This is a little tricky, as we must conform to the\r
- rules of exponential layout if necessary (e.g., we cannot end up\r
- with 10.0 if scientific). */\r
- if (after>=0) \r
- {setafter:for(;;){\r
- // calculate the current after-length\r
- {/*select*/\r
- if (num.form==com.ibm.icu.math.MathContext.PLAIN)\r
- thisafter=(int)-num.exp; // has decimal part\r
- else if (num.form==com.ibm.icu.math.MathContext.SCIENTIFIC)\r
- thisafter=num.mant.length-1;\r
- else{ // engineering\r
- lead=(((num.exp+num.mant.length)-1))%3; // exponent to use\r
- if (lead<0) \r
- lead=3+lead; // negative exponent case\r
- lead++; // number of leading digits\r
- if (lead>=num.mant.length) \r
- thisafter=0;\r
- else \r
- thisafter=num.mant.length-lead;\r
- }\r
- }\r
- if (thisafter==after) \r
- break setafter; // we're in luck\r
- if (thisafter<after) \r
- { // need added trailing zeros\r
- // [thisafter can be negative]\r
- newmant=extend(num.mant,(num.mant.length+after)-thisafter);\r
- num.mant=newmant;\r
- num.exp=num.exp-((after-thisafter)); // adjust exponent\r
- if (num.exp<MinExp) \r
- throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+num.exp);\r
- break setafter;\r
- }\r
- // We have too many digits after the decimal point; this could\r
- // cause a carry, which could change the mantissa...\r
- // Watch out for implied leading zeros in PLAIN case\r
- chop=thisafter-after; // digits to lop [is >0]\r
- if (chop>num.mant.length) \r
- { // all digits go, no chance of carry\r
- // carry on with zero\r
- num.mant=ZERO.mant;\r
- num.ind=iszero;\r
- num.exp=0;\r
- continue setafter; // recheck: we may need trailing zeros\r
- }\r
- // we have a digit to inspect from existing mantissa\r
- // round the number as required\r
- need=num.mant.length-chop; // digits to end up with [may be 0]\r
- oldexp=num.exp; // save old exponent\r
- num.round(need,exround);\r
- // if the exponent grew by more than the digits we chopped, then\r
- // we must have had a carry, so will need to recheck the layout\r
- if ((num.exp-oldexp)==chop) \r
- break setafter; // number did not have carry\r
- // mantissa got extended .. so go around and check again\r
- }\r
- }/*setafter*/\r
- \r
- a=num.layout(); // lay out, with exponent if required, etc.\r
- \r
- /* Here we have laid-out number in 'a' */\r
- // now apply 'before' and 'explaces' as needed\r
- if (before>0) \r
- {\r
- // look for '.' or 'E'\r
- {int $11=a.length;p=0;p:for(;$11>0;$11--,p++){\r
- if (a[p]=='.') \r
- break p;\r
- if (a[p]=='E') \r
- break p;\r
- }\r
- }/*p*/\r
- // p is now offset of '.', 'E', or character after end of array\r
- // that is, the current length of before part\r
- if (p>before) \r
- badarg("format",1,java.lang.String.valueOf(before)); // won't fit\r
- if (p<before) \r
- { // need leading blanks\r
- newa=new char[(a.length+before)-p];\r
- {int $12=before-p;i=0;for(;$12>0;$12--,i++){\r
- newa[i]=' ';\r
- }\r
- }/*i*/\r
- java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,i,a.length);\r
- a=newa;\r
- }\r
- // [if p=before then it's just the right length]\r
- }\r
- \r
- if (explaces>0) \r
- {\r
- // look for 'E' [cannot be at offset 0]\r
- {int $13=a.length-1;p=a.length-1;p:for(;$13>0;$13--,p--){\r
- if (a[p]=='E') \r
- break p;\r
- }\r
- }/*p*/\r
- // p is now offset of 'E', or 0\r
- if (p==0) \r
- { // no E part; add trailing blanks\r
- newa=new char[(a.length+explaces)+2];\r
- java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,0,a.length);\r
- {int $14=explaces+2;i=a.length;for(;$14>0;$14--,i++){\r
- newa[i]=' ';\r
- }\r
- }/*i*/\r
- a=newa;\r
- }\r
- else \r
- {/* found E */ // may need to insert zeros\r
- places=(a.length-p)-2; // number so far\r
- if (places>explaces) \r
- badarg("format",3,java.lang.String.valueOf(explaces));\r
- if (places<explaces) \r
- { // need to insert zeros\r
- newa=new char[(a.length+explaces)-places];\r
- java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,0,p+2); // through E and sign\r
- {int $15=explaces-places;i=p+2;for(;$15>0;$15--,i++){\r
- newa[i]='0';\r
- }\r
- }/*i*/\r
- java.lang.System.arraycopy((java.lang.Object)a,p+2,(java.lang.Object)newa,i,places); // remainder of exponent\r
- a=newa;\r
- }\r
- // [if places=explaces then it's just the right length]\r
- }\r
- }\r
- return new java.lang.String(a);\r
- }\r
-\r
- /**\r
- * Returns the hashcode for this <code>BigDecimal</code>.\r
- * This hashcode is suitable for use by the\r
- * <code>java.util.Hashtable</code> class.\r
- * <p>\r
- * Note that two <code>BigDecimal</code> objects are only guaranteed\r
- * to produce the same hashcode if they are exactly equal (that is,\r
- * the <code>String</code> representations of the\r
- * <code>BigDecimal</code> numbers are identical -- they have the same\r
- * characters in the same sequence).\r
- *\r
- * @return An <code>int</code> that is the hashcode for <code>this</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int hashCode(){\r
- // Maybe calculate ourselves, later. If so, note that there can be\r
- // more than one internal representation for a given toString() result.\r
- return this.toString().hashCode();\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to an <code>int</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part it is\r
- * discarded. If the <code>BigDecimal</code> is out of the possible\r
- * range for an <code>int</code> (32-bit signed integer) result then\r
- * only the low-order 32 bits are used. (That is, the number may be\r
- * <i>decapitated</i>.) To avoid unexpected errors when these\r
- * conditions occur, use the {@link #intValueExact} method.\r
- *\r
- * @return An <code>int</code> converted from <code>this</code>,\r
- * truncated and decapitated if necessary.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int intValue(){\r
- return toBigInteger().intValue();\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to an <code>int</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part or is\r
- * out of the possible range for an <code>int</code> (32-bit signed\r
- * integer) result then an <code>ArithmeticException</code> is thrown.\r
- *\r
- * @return An <code>int</code> equal in value to <code>this</code>.\r
- * @throws ArithmeticException if <code>this</code> has a non-zero\r
- * decimal part, or will not fit in an\r
- * <code>int</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int intValueExact(){\r
- int lodigit;\r
- int useexp=0;\r
- int result;\r
- int i=0;\r
- int topdig=0;\r
- // This does not use longValueExact() as the latter can be much\r
- // slower.\r
- // intcheck (from pow) relies on this to check decimal part\r
- if (ind==iszero) \r
- return 0; // easy, and quite common\r
- /* test and drop any trailing decimal part */\r
- lodigit=mant.length-1;\r
- if (exp<0) \r
- {\r
- lodigit=lodigit+exp; // reduces by -(-exp)\r
- /* all decimal places must be 0 */\r
- if ((!(allzero(mant,lodigit+1)))) \r
- throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());\r
- if (lodigit<0) \r
- return 0; // -1<this<1\r
- useexp=0;\r
- }\r
- else \r
- {/* >=0 */\r
- if ((exp+lodigit)>9) // early exit\r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- useexp=exp;\r
- }\r
- /* convert the mantissa to binary, inline for speed */\r
- result=0;\r
- {int $16=lodigit+useexp;i=0;for(;i<=$16;i++){\r
- result=result*10;\r
- if (i<=lodigit) \r
- result=result+mant[i];\r
- }\r
- }/*i*/\r
- \r
- /* Now, if the risky length, check for overflow */\r
- if ((lodigit+useexp)==9) \r
- {\r
- // note we cannot just test for -ve result, as overflow can move a\r
- // zero into the top bit [consider 5555555555]\r
- topdig=result/1000000000; // get top digit, preserving sign\r
- if (topdig!=mant[0]) \r
- { // digit must match and be positive\r
- // except in the special case ...\r
- if (result==java.lang.Integer.MIN_VALUE) // looks like the special\r
- if (ind==isneg) // really was negative\r
- if (mant[0]==2) \r
- return result; // really had top digit 2\r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- }\r
- }\r
- \r
- /* Looks good */\r
- if (ind==ispos) \r
- return result;\r
- return (int)-result;\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>long</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part it is\r
- * discarded. If the <code>BigDecimal</code> is out of the possible\r
- * range for a <code>long</code> (64-bit signed integer) result then\r
- * only the low-order 64 bits are used. (That is, the number may be\r
- * <i>decapitated</i>.) To avoid unexpected errors when these\r
- * conditions occur, use the {@link #longValueExact} method.\r
- *\r
- * @return A <code>long</code> converted from <code>this</code>,\r
- * truncated and decapitated if necessary.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public long longValue(){\r
- return toBigInteger().longValue();\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>long</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part or is\r
- * out of the possible range for a <code>long</code> (64-bit signed\r
- * integer) result then an <code>ArithmeticException</code> is thrown.\r
- *\r
- * @return A <code>long</code> equal in value to <code>this</code>.\r
- * @throws ArithmeticException if <code>this</code> has a non-zero\r
- * decimal part, or will not fit in a\r
- * <code>long</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public long longValueExact(){\r
- int lodigit;\r
- int cstart=0;\r
- int useexp=0;\r
- long result;\r
- int i=0;\r
- long topdig=0;\r
- // Identical to intValueExact except for result=long, and exp>=20 test\r
- if (ind==0) \r
- return 0; // easy, and quite common\r
- lodigit=mant.length-1; // last included digit\r
- if (exp<0) \r
- {\r
- lodigit=lodigit+exp; // -(-exp)\r
- /* all decimal places must be 0 */\r
- if (lodigit<0) \r
- cstart=0;\r
- else \r
- cstart=lodigit+1;\r
- if ((!(allzero(mant,cstart)))) \r
- throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());\r
- if (lodigit<0) \r
- return 0; // -1<this<1\r
- useexp=0;\r
- }\r
- else \r
- {/* >=0 */\r
- if ((exp+mant.length)>18) // early exit\r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- useexp=exp;\r
- }\r
- \r
- /* convert the mantissa to binary, inline for speed */\r
- // note that we could safely use the 'test for wrap to negative'\r
- // algorithm here, but instead we parallel the intValueExact\r
- // algorithm for ease of checking and maintenance.\r
- result=(long)0;\r
- {int $17=lodigit+useexp;i=0;for(;i<=$17;i++){\r
- result=result*10;\r
- if (i<=lodigit) \r
- result=result+mant[i];\r
- }\r
- }/*i*/\r
- \r
- /* Now, if the risky length, check for overflow */\r
- if ((lodigit+useexp)==18) \r
- {\r
- topdig=result/1000000000000000000L; // get top digit, preserving sign\r
- if (topdig!=mant[0]) \r
- { // digit must match and be positive\r
- // except in the special case ...\r
- if (result==java.lang.Long.MIN_VALUE) // looks like the special\r
- if (ind==isneg) // really was negative\r
- if (mant[0]==9) \r
- return result; // really had top digit 9\r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- }\r
- }\r
- \r
- /* Looks good */\r
- if (ind==ispos) \r
- return result;\r
- return (long)-result;\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose decimal point has\r
- * been moved to the left by a specified number of positions.\r
- * The parameter, <code>n</code>, specifies the number of positions to\r
- * move the decimal point.\r
- * That is, if <code>n</code> is 0 or positive, the number returned is\r
- * given by:\r
- * <p><code>\r
- * this.multiply(TEN.pow(new BigDecimal(-n)))\r
- * </code>\r
- * <p>\r
- * <code>n</code> may be negative, in which case the method returns\r
- * the same result as <code>movePointRight(-n)</code>.\r
- *\r
- * @param n The <code>int</code> specifying the number of places to\r
- * move the decimal point leftwards.\r
- * @return A <code>BigDecimal</code> derived from\r
- * <code>this</code>, with the decimal point moved\r
- * <code>n</code> places to the left.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal movePointLeft(int n){\r
- com.ibm.icu.math.BigDecimal res;\r
- // very little point in optimizing for shift of 0\r
- res=clone(this);\r
- res.exp=res.exp-n;\r
- return res.finish(plainMC,false); // finish sets form and checks exponent\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> whose decimal point has\r
- * been moved to the right by a specified number of positions.\r
- * The parameter, <code>n</code>, specifies the number of positions to\r
- * move the decimal point.\r
- * That is, if <code>n</code> is 0 or positive, the number returned is\r
- * given by:\r
- * <p><code>\r
- * this.multiply(TEN.pow(new BigDecimal(n)))\r
- * </code>\r
- * <p>\r
- * <code>n</code> may be negative, in which case the method returns\r
- * the same result as <code>movePointLeft(-n)</code>.\r
- *\r
- * @param n The <code>int</code> specifying the number of places to\r
- * move the decimal point rightwards.\r
- * @return A <code>BigDecimal</code> derived from\r
- * <code>this</code>, with the decimal point moved\r
- * <code>n</code> places to the right.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal movePointRight(int n){\r
- com.ibm.icu.math.BigDecimal res;\r
- res=clone(this);\r
- res.exp=res.exp+n;\r
- return res.finish(plainMC,false);\r
- }\r
-\r
- /**\r
- * Returns the scale of this <code>BigDecimal</code>.\r
- * Returns a non-negative <code>int</code> which is the scale of the\r
- * number. The scale is the number of digits in the decimal part of\r
- * the number if the number were formatted without exponential\r
- * notation.\r
- *\r
- * @return An <code>int</code> whose value is the scale of this\r
- * <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int scale(){\r
- if (exp>=0) \r
- return 0; // scale can never be negative\r
- return (int)-exp;\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> with a given scale.\r
- * <p>\r
- * If the given scale (which must be zero or positive) is the same as\r
- * or greater than the length of the decimal part (the scale) of this\r
- * <code>BigDecimal</code> then trailing zeros will be added to the\r
- * decimal part as necessary.\r
- * <p>\r
- * If the given scale is less than the length of the decimal part (the\r
- * scale) of this <code>BigDecimal</code> then trailing digits\r
- * will be removed, and in this case an\r
- * <code>ArithmeticException</code> is thrown if any discarded digits\r
- * are non-zero.\r
- * <p>\r
- * The same as {@link #setScale(int, int)}, where the first parameter\r
- * is the scale, and the second is\r
- * <code>MathContext.ROUND_UNNECESSARY</code>.\r
- *\r
- * @param scale The <code>int</code> specifying the scale of the\r
- * resulting <code>BigDecimal</code>.\r
- * @return A plain <code>BigDecimal</code> with the given scale.\r
- * @throws ArithmeticException if <code>scale</code> is negative.\r
- * @throws ArithmeticException if reducing scale would discard\r
- * non-zero digits.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal setScale(int scale){\r
- return setScale(scale,ROUND_UNNECESSARY);\r
- }\r
-\r
- /**\r
- * Returns a plain <code>BigDecimal</code> with a given scale.\r
- * <p>\r
- * If the given scale (which must be zero or positive) is the same as\r
- * or greater than the length of the decimal part (the scale) of this\r
- * <code>BigDecimal</code> then trailing zeros will be added to the\r
- * decimal part as necessary.\r
- * <p>\r
- * If the given scale is less than the length of the decimal part (the\r
- * scale) of this <code>BigDecimal</code> then trailing digits\r
- * will be removed, and the rounding mode given by the second\r
- * parameter is used to determine if the remaining digits are\r
- * affected by a carry.\r
- * In this case, an <code>IllegalArgumentException</code> is thrown if\r
- * <code>round</code> is not a valid rounding mode.\r
- * <p>\r
- * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>,\r
- * an <code>ArithmeticException</code> is thrown if any discarded\r
- * digits are non-zero.\r
- *\r
- * @param scale The <code>int</code> specifying the scale of the\r
- * resulting <code>BigDecimal</code>.\r
- * @param round The <code>int</code> rounding mode to be used for\r
- * the division (see the {@link MathContext} class).\r
- * @return A plain <code>BigDecimal</code> with the given scale.\r
- * @throws IllegalArgumentException if <code>round</code> is not a\r
- * valid rounding mode.\r
- * @throws ArithmeticException if <code>scale</code> is negative.\r
- * @throws ArithmeticException if <code>round</code> is\r
- * <code>MathContext.ROUND_UNNECESSARY</code>, and\r
- * reducing scale would discard non-zero digits.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public com.ibm.icu.math.BigDecimal setScale(int scale,int round){\r
- int ourscale;\r
- com.ibm.icu.math.BigDecimal res;\r
- int padding=0;\r
- int newlen=0;\r
- // at present this naughtily only checks the round value if it is\r
- // needed (used), for speed\r
- ourscale=this.scale();\r
- if (ourscale==scale) // already correct scale\r
- if (this.form==com.ibm.icu.math.MathContext.PLAIN) // .. and form\r
- return this;\r
- res=clone(this); // need copy\r
- if (ourscale<=scale) \r
- { // simply zero-padding/changing form\r
- // if ourscale is 0 we may have lots of 0s to add\r
- if (ourscale==0) \r
- padding=res.exp+scale;\r
- else \r
- padding=scale-ourscale;\r
- res.mant=extend(res.mant,res.mant.length+padding);\r
- res.exp=(int)-scale; // as requested\r
- }\r
- else \r
- {/* ourscale>scale: shortening, probably */\r
- if (scale<0) \r
- throw new java.lang.ArithmeticException("Negative scale:"+" "+scale);\r
- // [round() will raise exception if invalid round]\r
- newlen=res.mant.length-((ourscale-scale)); // [<=0 is OK]\r
- res=res.round(newlen,round); // round to required length\r
- // This could have shifted left if round (say) 0.9->1[.0]\r
- // Repair if so by adding a zero and reducing exponent\r
- if (res.exp!=((int)-scale)) \r
- {\r
- res.mant=extend(res.mant,res.mant.length+1);\r
- res.exp=res.exp-1;\r
- }\r
- }\r
- res.form=(byte)com.ibm.icu.math.MathContext.PLAIN; // by definition\r
- return res;\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a <code>short</code>.\r
- * If the <code>BigDecimal</code> has a non-zero decimal part or is\r
- * out of the possible range for a <code>short</code> (16-bit signed\r
- * integer) result then an <code>ArithmeticException</code> is thrown.\r
- *\r
- * @return A <code>short</code> equal in value to <code>this</code>.\r
- * @throws ArithmeticException if <code>this</code> has a non-zero\r
- * decimal part, or will not fit in a\r
- * <code>short</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public short shortValueExact(){\r
- int num;\r
- num=this.intValueExact(); // will check decimal part too\r
- if ((num>32767)|(num<(-32768))) \r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());\r
- return (short)num;\r
- }\r
-\r
- /**\r
- * Returns the sign of this <code>BigDecimal</code>, as an\r
- * <code>int</code>.\r
- * This returns the <i>signum</i> function value that represents the\r
- * sign of this <code>BigDecimal</code>.\r
- * That is, -1 if the <code>BigDecimal</code> is negative, 0 if it is\r
- * numerically equal to zero, or 1 if it is positive.\r
- *\r
- * @return An <code>int</code> which is -1 if the\r
- * <code>BigDecimal</code> is negative, 0 if it is\r
- * numerically equal to zero, or 1 if it is positive.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public int signum(){\r
- return (int)this.ind; // [note this assumes values for ind.]\r
- }\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
- /**\r
- * Converts this <code>BigDecimal</code> to a\r
- * <code>java.math.BigDecimal</code>.\r
- * <p>\r
- * This is an exact conversion; the result is the same as if the\r
- * <code>BigDecimal</code> were formatted as a plain number without\r
- * any rounding or exponent and then the\r
- * <code>java.math.BigDecimal(java.lang.String)</code> constructor\r
- * were used to construct the result.\r
- * <p>\r
- * <i>(Note: this method is provided only in the\r
- * <code>com.ibm.icu.math</code> version of the BigDecimal class.\r
- * It would not be present in a <code>java.math</code> version.)</i>\r
- *\r
- * @return The <code>java.math.BigDecimal</code> equal in value\r
- * to this <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.math.BigDecimal toBigDecimal(){\r
- return new java.math.BigDecimal(this.unscaledValue(),this.scale());\r
- }\r
-//#endif\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a\r
- * <code>java.math.BigInteger</code>.\r
- * <p>\r
- * Any decimal part is truncated (discarded).\r
- * If an exception is desired should the decimal part be non-zero,\r
- * use {@link #toBigIntegerExact()}.\r
- *\r
- * @return The <code>java.math.BigInteger</code> equal in value\r
- * to the integer part of this <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.math.BigInteger toBigInteger(){\r
- com.ibm.icu.math.BigDecimal res=null;\r
- int newlen=0;\r
- byte newmant[]=null;\r
- {/*select*/\r
- if ((exp>=0)&(form==com.ibm.icu.math.MathContext.PLAIN))\r
- res=this; // can layout simply\r
- else if (exp>=0)\r
- {\r
- res=clone(this); // safe copy\r
- res.form=(byte)com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN\r
- }\r
- else{\r
- { // exp<0; scale to be truncated\r
- // we could use divideInteger, but we may as well be quicker\r
- if (((int)-this.exp)>=this.mant.length) \r
- res=ZERO; // all blows away\r
- else \r
- {\r
- res=clone(this); // safe copy\r
- newlen=res.mant.length+res.exp;\r
- newmant=new byte[newlen]; // [shorter]\r
- java.lang.System.arraycopy((java.lang.Object)res.mant,0,(java.lang.Object)newmant,0,newlen);\r
- res.mant=newmant;\r
- res.form=(byte)com.ibm.icu.math.MathContext.PLAIN;\r
- res.exp=0;\r
- }\r
- }\r
- }\r
- }\r
- return new BigInteger(new java.lang.String(res.layout()));\r
- }\r
-\r
- /**\r
- * Converts this <code>BigDecimal</code> to a\r
- * <code>java.math.BigInteger</code>.\r
- * <p>\r
- * An exception is thrown if the decimal part (if any) is non-zero.\r
- *\r
- * @return The <code>java.math.BigInteger</code> equal in value\r
- * to the integer part of this <code>BigDecimal</code>.\r
- * @throws ArithmeticException if <code>this</code> has a non-zero\r
- * decimal part.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.math.BigInteger toBigIntegerExact(){\r
- /* test any trailing decimal part */\r
- if (exp<0) \r
- { // possible decimal part\r
- /* all decimal places must be 0; note exp<0 */\r
- if ((!(allzero(mant,mant.length+exp)))) \r
- throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());\r
- }\r
- return toBigInteger();\r
- }\r
-\r
- /**\r
- * Returns the <code>BigDecimal</code> as a character array.\r
- * The result of this method is the same as using the\r
- * sequence <code>toString().toCharArray()</code>, but avoids creating\r
- * the intermediate <code>String</code> and <code>char[]</code>\r
- * objects.\r
- *\r
- * @return The <code>char[]</code> array corresponding to this\r
- * <code>BigDecimal</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public char[] toCharArray(){\r
- return layout();\r
- }\r
-\r
- /**\r
- * Returns the <code>BigDecimal</code> as a <code>String</code>.\r
- * This returns a <code>String</code> that exactly represents this\r
- * <code>BigDecimal</code>, as defined in the decimal documentation\r
- * (see {@link BigDecimal class header}).\r
- * <p>\r
- * By definition, using the {@link #BigDecimal(String)} constructor\r
- * on the result <code>String</code> will create a\r
- * <code>BigDecimal</code> that is exactly equal to the original\r
- * <code>BigDecimal</code>.\r
- *\r
- * @return The <code>String</code> exactly corresponding to this\r
- * <code>BigDecimal</code>.\r
- * @see #format(int, int)\r
- * @see #format(int, int, int, int, int, int)\r
- * @see #toCharArray()\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.lang.String toString(){\r
- return new java.lang.String(layout());\r
- }\r
-\r
- /**\r
- * Returns the number as a <code>BigInteger</code> after removing the\r
- * scale.\r
- * That is, the number is expressed as a plain number, any decimal\r
- * point is then removed (retaining the digits of any decimal part),\r
- * and the result is then converted to a <code>BigInteger</code>.\r
- *\r
- * @return The <code>java.math.BigInteger</code> equal in value to\r
- * this <code>BigDecimal</code> multiplied by ten to the\r
- * power of <code>this.scale()</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public java.math.BigInteger unscaledValue(){\r
- com.ibm.icu.math.BigDecimal res=null;\r
- if (exp>=0) \r
- res=this;\r
- else \r
- {\r
- res=clone(this); // safe copy\r
- res.exp=0; // drop scale\r
- }\r
- return res.toBigInteger();\r
- }\r
-\r
- /**\r
- * Translates a <code>double</code> to a <code>BigDecimal</code>.\r
- * <p>\r
- * Returns a <code>BigDecimal</code> which is the decimal\r
- * representation of the 64-bit signed binary floating point\r
- * parameter. If the parameter is infinite, or is not a number (NaN),\r
- * a <code>NumberFormatException</code> is thrown.\r
- * <p>\r
- * The number is constructed as though <code>num</code> had been\r
- * converted to a <code>String</code> using the\r
- * <code>Double.toString()</code> method and the\r
- * {@link #BigDecimal(java.lang.String)} constructor had then been used.\r
- * This is typically not an exact conversion.\r
- *\r
- * @param dub The <code>double</code> to be translated.\r
- * @return The <code>BigDecimal</code> equal in value to\r
- * <code>dub</code>.\r
- * @throws NumberFormatException if the parameter is infinite or\r
- * not a number.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public static com.ibm.icu.math.BigDecimal valueOf(double dub){\r
- // Reminder: a zero double returns '0.0', so we cannot fastpath to\r
- // use the constant ZERO. This might be important enough to justify\r
- // a factory approach, a cache, or a few private constants, later.\r
- return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());\r
- }\r
-\r
- /**\r
- * Translates a <code>long</code> to a <code>BigDecimal</code>.\r
- * That is, returns a plain <code>BigDecimal</code> whose value is\r
- * equal to the given <code>long</code>.\r
- *\r
- * @param lint The <code>long</code> to be translated.\r
- * @return The <code>BigDecimal</code> equal in value to\r
- * <code>lint</code>.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public static com.ibm.icu.math.BigDecimal valueOf(long lint){\r
- return valueOf(lint,0);\r
- }\r
-\r
- /**\r
- * Translates a <code>long</code> to a <code>BigDecimal</code> with a\r
- * given scale.\r
- * That is, returns a plain <code>BigDecimal</code> whose unscaled\r
- * value is equal to the given <code>long</code>, adjusted by the\r
- * second parameter, <code>scale</code>.\r
- * <p>\r
- * The result is given by:\r
- * <p><code>\r
- * (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale)))\r
- * </code>\r
- * <p>\r
- * A <code>NumberFormatException</code> is thrown if <code>scale</code>\r
- * is negative.\r
- *\r
- * @param lint The <code>long</code> to be translated.\r
- * @param scale The <code>int</code> scale to be applied.\r
- * @return The <code>BigDecimal</code> equal in value to\r
- * <code>lint</code>.\r
- * @throws NumberFormatException if the scale is negative.\r
- * @stable ICU 2.0\r
- */\r
- \r
- public static com.ibm.icu.math.BigDecimal valueOf(long lint,int scale){\r
- com.ibm.icu.math.BigDecimal res=null;\r
- {/*select*/\r
- if (lint==0)\r
- res=ZERO;\r
- else if (lint==1)\r
- res=ONE;\r
- else if (lint==10)\r
- res=TEN;\r
- else{\r
- res=new com.ibm.icu.math.BigDecimal(lint);\r
- }\r
- }\r
- if (scale==0) \r
- return res;\r
- if (scale<0) \r
- throw new java.lang.NumberFormatException("Negative scale:"+" "+scale);\r
- res=clone(res); // safe copy [do not mutate]\r
- res.exp=(int)-scale; // exponent is -scale\r
- return res;\r
- }\r
-\r
- /* ---------------------------------------------------------------- */\r
- /* Private methods */\r
- /* ---------------------------------------------------------------- */\r
- \r
- /* <sgml> Return char array value of a BigDecimal (conversion from\r
- BigDecimal to laid-out canonical char array).\r
- <p>The mantissa will either already have been rounded (following an\r
- operation) or will be of length appropriate (in the case of\r
- construction from an int, for example).\r
- <p>We must not alter the mantissa, here.\r
- <p>'form' describes whether we are to use exponential notation (and\r
- if so, which), or if we are to lay out as a plain/pure numeric.\r
- </sgml> */\r
- \r
- private char[] layout(){\r
- char cmant[];\r
- int i=0;\r
- java.lang.StringBuffer sb=null;\r
- int euse=0;\r
- int sig=0;\r
- char csign=0;\r
- char rec[]=null;\r
- int needsign;\r
- int mag;\r
- int len=0;\r
- cmant=new char[mant.length]; // copy byte[] to a char[]\r
- {int $18=mant.length;i=0;for(;$18>0;$18--,i++){\r
- cmant[i]=(char)(mant[i]+((int)('0')));\r
- }\r
- }/*i*/\r
- \r
- if (form!=com.ibm.icu.math.MathContext.PLAIN) \r
- {/* exponential notation needed */\r
- sb=new java.lang.StringBuffer(cmant.length+15); // -x.xxxE+999999999\r
- if (ind==isneg) \r
- sb.append('-');\r
- euse=(exp+cmant.length)-1; // exponent to use\r
- /* setup sig=significant digits and copy to result */\r
- if (form==com.ibm.icu.math.MathContext.SCIENTIFIC) \r
- { // [default]\r
- sb.append(cmant[0]); // significant character\r
- if (cmant.length>1) // have decimal part\r
- sb.append('.').append(cmant,1,cmant.length-1);\r
- }\r
- else \r
- {do{\r
- sig=euse%3; // common\r
- if (sig<0) \r
- sig=3+sig; // negative exponent\r
- euse=euse-sig;\r
- sig++;\r
- if (sig>=cmant.length) \r
- { // zero padding may be needed\r
- sb.append(cmant,0,cmant.length);\r
- {int $19=sig-cmant.length;for(;$19>0;$19--){\r
- sb.append('0');\r
- }\r
- }\r
- }\r
- else \r
- { // decimal point needed\r
- sb.append(cmant,0,sig).append('.').append(cmant,sig,cmant.length-sig);\r
- }\r
- }while(false);}/*engineering*/\r
- if (euse!=0) \r
- {\r
- if (euse<0) \r
- {\r
- csign='-';\r
- euse=(int)-euse;\r
- }\r
- else \r
- csign='+';\r
- sb.append('E').append(csign).append(euse);\r
- }\r
- rec=new char[sb.length()];\r
- Utility.getChars(sb, 0,sb.length(),rec,0);\r
- return rec;\r
- }\r
- \r
- /* Here for non-exponential (plain) notation */\r
- if (exp==0) \r
- {/* easy */\r
- if (ind>=0) \r
- return cmant; // non-negative integer\r
- rec=new char[cmant.length+1];\r
- rec[0]='-';\r
- java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,1,cmant.length);\r
- return rec;\r
- }\r
- \r
- /* Need a '.' and/or some zeros */\r
- needsign=(int)((ind==isneg)?1:0); // space for sign? 0 or 1\r
- \r
- /* MAG is the position of the point in the mantissa (index of the\r
- character it follows) */\r
- mag=exp+cmant.length;\r
- \r
- if (mag<1) \r
- {/* 0.00xxxx form */\r
- len=(needsign+2)-exp; // needsign+2+(-mag)+cmant.length\r
- rec=new char[len];\r
- if (needsign!=0) \r
- rec[0]='-';\r
- rec[needsign]='0';\r
- rec[needsign+1]='.';\r
- {int $20=(int)-mag;i=needsign+2;for(;$20>0;$20--,i++){ // maybe none\r
- rec[i]='0';\r
- }\r
- }/*i*/\r
- java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,(needsign+2)-mag,cmant.length);\r
- return rec;\r
- }\r
- \r
- if (mag>cmant.length) \r
- {/* xxxx0000 form */\r
- len=needsign+mag;\r
- rec=new char[len];\r
- if (needsign!=0) \r
- rec[0]='-';\r
- java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,needsign,cmant.length);\r
- {int $21=mag-cmant.length;i=needsign+cmant.length;for(;$21>0;$21--,i++){ // never 0\r
- rec[i]='0';\r
- }\r
- }/*i*/\r
- return rec;\r
- }\r
- \r
- /* decimal point is in the middle of the mantissa */\r
- len=(needsign+1)+cmant.length;\r
- rec=new char[len];\r
- if (needsign!=0) \r
- rec[0]='-';\r
- java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,needsign,mag);\r
- rec[needsign+mag]='.';\r
- java.lang.System.arraycopy((java.lang.Object)cmant,mag,(java.lang.Object)rec,(needsign+mag)+1,cmant.length-mag);\r
- return rec;\r
- }\r
-\r
- /* <sgml> Checks a BigDecimal argument to ensure it's a true integer\r
- in a given range.\r
- <p>If OK, returns it as an int. </sgml> */\r
- // [currently only used by pow]\r
- \r
- private int intcheck(int min,int max){\r
- int i;\r
- i=this.intValueExact(); // [checks for non-0 decimal part]\r
- // Use same message as though intValueExact failed due to size\r
- if ((i<min)|(i>max)) \r
- throw new java.lang.ArithmeticException("Conversion overflow:"+" "+i);\r
- return i;\r
- }\r
-\r
- /* <sgml> Carry out division operations. </sgml> */\r
- /*\r
- Arg1 is operation code: D=divide, I=integer divide, R=remainder\r
- Arg2 is the rhs.\r
- Arg3 is the context.\r
- Arg4 is explicit scale iff code='D' or 'I' (-1 if none).\r
- \r
- Underlying algorithm (complications for Remainder function and\r
- scaled division are omitted for clarity):\r
- \r
- Test for x/0 and then 0/x\r
- Exp =Exp1 - Exp2\r
- Exp =Exp +len(var1) -len(var2)\r
- Sign=Sign1 * Sign2\r
- Pad accumulator (Var1) to double-length with 0's (pad1)\r
- Pad Var2 to same length as Var1\r
- B2B=1st two digits of var2, +1 to allow for roundup\r
- have=0\r
- Do until (have=digits+1 OR residue=0)\r
- if exp<0 then if integer divide/residue then leave\r
- this_digit=0\r
- Do forever\r
- compare numbers\r
- if <0 then leave inner_loop\r
- if =0 then (- quick exit without subtract -) do\r
- this_digit=this_digit+1; output this_digit\r
- leave outer_loop; end\r
- Compare lengths of numbers (mantissae):\r
- If same then CA=first_digit_of_Var1\r
- else CA=first_two_digits_of_Var1\r
- mult=ca*10/b2b -- Good and safe guess at divisor\r
- if mult=0 then mult=1\r
- this_digit=this_digit+mult\r
- subtract\r
- end inner_loop\r
- if have\=0 | this_digit\=0 then do\r
- output this_digit\r
- have=have+1; end\r
- var2=var2/10\r
- exp=exp-1\r
- end outer_loop\r
- exp=exp+1 -- set the proper exponent\r
- if have=0 then generate answer=0\r
- Return to FINISHED\r
- Result defined by MATHV1\r
- \r
- For extended commentary, see DMSRCN.\r
- */\r
- \r
- private com.ibm.icu.math.BigDecimal dodivide(char code,com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set,int scale){\r
- com.ibm.icu.math.BigDecimal lhs;\r
- int reqdig;\r
- int newexp;\r
- com.ibm.icu.math.BigDecimal res;\r
- int newlen;\r
- byte var1[];\r
- int var1len;\r
- byte var2[];\r
- int var2len;\r
- int b2b;\r
- int have;\r
- int thisdigit=0;\r
- int i=0;\r
- byte v2=0;\r
- int ba=0;\r
- int mult=0;\r
- int start=0;\r
- int padding=0;\r
- int d=0;\r
- byte newvar1[]=null;\r
- byte lasthave=0;\r
- int actdig=0;\r
- byte newmant[]=null;\r
- \r
- if (set.lostDigits) \r
- checkdigits(rhs,set.digits);\r
- lhs=this; // name for clarity\r
- \r
- // [note we must have checked lostDigits before the following checks]\r
- if (rhs.ind==0) \r
- throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0\r
- if (lhs.ind==0) \r
- { // 0/x => 0 [possibly with .0s]\r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN) \r
- return ZERO;\r
- if (scale==(-1)) \r
- return lhs;\r
- return lhs.setScale(scale);\r
- }\r
- \r
- /* Prepare numbers according to BigDecimal rules */\r
- reqdig=set.digits; // local copy (heavily used)\r
- if (reqdig>0) \r
- {\r
- if (lhs.mant.length>reqdig) \r
- lhs=clone(lhs).round(set);\r
- if (rhs.mant.length>reqdig) \r
- rhs=clone(rhs).round(set);\r
- }\r
- else \r
- {/* scaled divide */\r
- if (scale==(-1)) \r
- scale=lhs.scale();\r
- // set reqdig to be at least large enough for the computation\r
- reqdig=lhs.mant.length; // base length\r
- // next line handles both positive lhs.exp and also scale mismatch\r
- if (scale!=((int)-lhs.exp)) \r
- reqdig=(reqdig+scale)+lhs.exp;\r
- reqdig=(reqdig-((rhs.mant.length-1)))-rhs.exp; // reduce by RHS effect\r
- if (reqdig<lhs.mant.length) \r
- reqdig=lhs.mant.length; // clamp\r
- if (reqdig<rhs.mant.length) \r
- reqdig=rhs.mant.length; // ..\r
- }\r
- \r
- /* precalculate exponent */\r
- newexp=((lhs.exp-rhs.exp)+lhs.mant.length)-rhs.mant.length;\r
- /* If new exponent -ve, then some quick exits are possible */\r
- if (newexp<0) \r
- if (code!='D') \r
- {\r
- if (code=='I') \r
- return ZERO; // easy - no integer part\r
- /* Must be 'R'; remainder is [finished clone of] input value */\r
- return clone(lhs).finish(set,false);\r
- }\r
- \r
- /* We need slow division */\r
- res=new com.ibm.icu.math.BigDecimal(); // where we'll build result\r
- res.ind=(byte)(lhs.ind*rhs.ind); // final sign (for D/I)\r
- res.exp=newexp; // initial exponent (for D/I)\r
- res.mant=new byte[reqdig+1]; // where build the result\r
- \r
- /* Now [virtually pad the mantissae with trailing zeros */\r
- // Also copy the LHS, which will be our working array\r
- newlen=(reqdig+reqdig)+1;\r
- var1=extend(lhs.mant,newlen); // always makes longer, so new safe array\r
- var1len=newlen; // [remaining digits are 0]\r
- \r
- var2=rhs.mant;\r
- var2len=newlen;\r
- \r
- /* Calculate first two digits of rhs (var2), +1 for later estimations */\r
- b2b=(var2[0]*10)+1;\r
- if (var2.length>1) \r
- b2b=b2b+var2[1];\r
- \r
- /* start the long-division loops */\r
- have=0;\r
- {outer:for(;;){\r
- thisdigit=0;\r
- /* find the next digit */\r
- {inner:for(;;){\r
- if (var1len<var2len) \r
- break inner; // V1 too low\r
- if (var1len==var2len) \r
- { // compare needed\r
- {compare:do{ // comparison\r
- {int $22=var1len;i=0;for(;$22>0;$22--,i++){\r
- // var1len is always <= var1.length\r
- if (i<var2.length) \r
- v2=var2[i];\r
- else \r
- v2=(byte)0;\r
- if (var1[i]<v2) \r
- break inner; // V1 too low\r
- if (var1[i]>v2) \r
- break compare; // OK to subtract\r
- }\r
- }/*i*/\r
- /* reach here if lhs and rhs are identical; subtraction will\r
- increase digit by one, and the residue will be 0 so we\r
- are done; leave the loop with residue set to 0 (in case\r
- code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is\r
- being checked) */\r
- thisdigit++;\r
- res.mant[have]=(byte)thisdigit;\r
- have++;\r
- var1[0]=(byte)0; // residue to 0 [this is all we'll test]\r
- // var1len=1 -- [optimized out]\r
- break outer;\r
- }while(false);}/*compare*/\r
- /* prepare for subtraction. Estimate BA (lengths the same) */\r
- ba=(int)var1[0]; // use only first digit\r
- } // lengths the same\r
- else \r
- {/* lhs longer than rhs */\r
- /* use first two digits for estimate */\r
- ba=var1[0]*10;\r
- if (var1len>1) \r
- ba=ba+var1[1];\r
- }\r
- /* subtraction needed; V1>=V2 */\r
- mult=(ba*10)/b2b;\r
- if (mult==0) \r
- mult=1;\r
- thisdigit=thisdigit+mult;\r
- // subtract; var1 reusable\r
- var1=byteaddsub(var1,var1len,var2,var2len,(int)-mult,true);\r
- if (var1[0]!=0) \r
- continue inner; // maybe another subtract needed\r
- /* V1 now probably has leading zeros, remove leading 0's and try\r
- again. (It could be longer than V2) */\r
- {int $23=var1len-2;start=0;start:for(;start<=$23;start++){\r
- if (var1[start]!=0) \r
- break start;\r
- var1len--;\r
- }\r
- }/*start*/\r
- if (start==0) \r
- continue inner;\r
- // shift left\r
- java.lang.System.arraycopy((java.lang.Object)var1,start,(java.lang.Object)var1,0,var1len);\r
- }\r
- }/*inner*/\r
- \r
- /* We have the next digit */\r
- if ((have!=0)|(thisdigit!=0)) \r
- { // put the digit we got\r
- res.mant[have]=(byte)thisdigit;\r
- have++;\r
- if (have==(reqdig+1)) \r
- break outer; // we have all we need\r
- if (var1[0]==0) \r
- break outer; // residue now 0\r
- }\r
- /* can leave now if a scaled divide and exponent is small enough */\r
- if (scale>=0) \r
- if (((int)-res.exp)>scale) \r
- break outer;\r
- /* can leave now if not Divide and no integer part left */\r
- if (code!='D') \r
- if (res.exp<=0) \r
- break outer;\r
- res.exp=res.exp-1; // reduce the exponent\r
- /* to get here, V1 is less than V2, so divide V2 by 10 and go for\r
- the next digit */\r
- var2len--;\r
- }\r
- }/*outer*/\r
- \r
- /* here when we have finished dividing, for some reason */\r
- // have is the number of digits we collected in res.mant\r
- if (have==0) \r
- have=1; // res.mant[0] is 0; we always want a digit\r
- \r
- if ((code=='I')|(code=='R')) \r
- {/* check for integer overflow needed */\r
- if ((have+res.exp)>reqdig) \r
- throw new java.lang.ArithmeticException("Integer overflow");\r
- \r
- if (code=='R') \r
- {do{\r
- /* We were doing Remainder -- return the residue */\r
- if (res.mant[0]==0) // no integer part was found\r
- return clone(lhs).finish(set,false); // .. so return lhs, canonical\r
- if (var1[0]==0) \r
- return ZERO; // simple 0 residue\r
- res.ind=lhs.ind; // sign is always as LHS\r
- /* Calculate the exponent by subtracting the number of padding zeros\r
- we added and adding the original exponent */\r
- padding=((reqdig+reqdig)+1)-lhs.mant.length;\r
- res.exp=(res.exp-padding)+lhs.exp;\r
- \r
- /* strip insignificant padding zeros from residue, and create/copy\r
- the resulting mantissa if need be */\r
- d=var1len;\r
- {i=d-1;i:for(;i>=1;i--){if(!((res.exp<lhs.exp)&(res.exp<rhs.exp)))break;\r
- if (var1[i]!=0) \r
- break i;\r
- d--;\r
- res.exp=res.exp+1;\r
- }\r
- }/*i*/\r
- if (d<var1.length) \r
- {/* need to reduce */\r
- newvar1=new byte[d];\r
- java.lang.System.arraycopy((java.lang.Object)var1,0,(java.lang.Object)newvar1,0,d); // shorten\r
- var1=newvar1;\r
- }\r
- res.mant=var1;\r
- return res.finish(set,false);\r
- }while(false);}/*remainder*/\r
- }\r
- \r
- else \r
- {/* 'D' -- no overflow check needed */\r
- // If there was a residue then bump the final digit (iff 0 or 5)\r
- // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and\r
- // ROUND_UNNECESSARY checks (etc.) later.\r
- // [if we finished early, the residue will be 0]\r
- if (var1[0]!=0) \r
- { // residue not 0\r
- lasthave=res.mant[have-1];\r
- if (((lasthave%5))==0) \r
- res.mant[have-1]=(byte)(lasthave+1);\r
- }\r
- }\r
- \r
- /* Here for Divide or Integer Divide */\r
- // handle scaled results first ['I' always scale 0, optional for 'D']\r
- if (scale>=0) \r
- {do{\r
- // say 'scale have res.exp len' scale have res.exp res.mant.length\r
- if (have!=res.mant.length) \r
- // already padded with 0's, so just adjust exponent\r
- res.exp=res.exp-((res.mant.length-have));\r
- // calculate number of digits we really want [may be 0]\r
- actdig=res.mant.length-((((int)-res.exp)-scale));\r
- res.round(actdig,set.roundingMode); // round to desired length\r
- // This could have shifted left if round (say) 0.9->1[.0]\r
- // Repair if so by adding a zero and reducing exponent\r
- if (res.exp!=((int)-scale)) \r
- {\r
- res.mant=extend(res.mant,res.mant.length+1);\r
- res.exp=res.exp-1;\r
- }\r
- return res.finish(set,true); // [strip if not PLAIN]\r
- }while(false);}/*scaled*/\r
- \r
- // reach here only if a non-scaled\r
- if (have==res.mant.length) \r
- { // got digits+1 digits\r
- res.round(set);\r
- have=reqdig;\r
- }\r
- else \r
- {/* have<=reqdig */\r
- if (res.mant[0]==0) \r
- return ZERO; // fastpath\r
- // make the mantissa truly just 'have' long\r
- // [we could let finish do this, during strip, if we adjusted\r
- // the exponent; however, truncation avoids the strip loop]\r
- newmant=new byte[have]; // shorten\r
- java.lang.System.arraycopy((java.lang.Object)res.mant,0,(java.lang.Object)newmant,0,have);\r
- res.mant=newmant;\r
- }\r
- return res.finish(set,true);\r
- }\r
-\r
- \r
- /* <sgml> Report a conversion exception. </sgml> */\r
- \r
- private void bad(char s[]){\r
- throw new java.lang.NumberFormatException("Not a number:"+" "+java.lang.String.valueOf(s));\r
- }\r
-\r
- /* <sgml> Report a bad argument to a method. </sgml>\r
- Arg1 is method name\r
- Arg2 is argument position\r
- Arg3 is what was found */\r
- \r
- private void badarg(java.lang.String name,int pos,java.lang.String value){\r
- throw new java.lang.IllegalArgumentException("Bad argument"+" "+pos+" "+"to"+" "+name+":"+" "+value);\r
- }\r
-\r
- /* <sgml> Extend byte array to given length, padding with 0s. If no\r
- extension is required then return the same array. </sgml>\r
- \r
- Arg1 is the source byte array\r
- Arg2 is the new length (longer)\r
- */\r
- \r
- private static final byte[] extend(byte inarr[],int newlen){\r
- byte newarr[];\r
- if (inarr.length==newlen) \r
- return inarr;\r
- newarr=new byte[newlen];\r
- java.lang.System.arraycopy((java.lang.Object)inarr,0,(java.lang.Object)newarr,0,inarr.length);\r
- // 0 padding is carried out by the JVM on allocation initialization\r
- return newarr;\r
- }\r
-\r
- /* <sgml> Add or subtract two >=0 integers in byte arrays\r
- <p>This routine performs the calculation:\r
- <pre>\r
- C=A+(B*M)\r
- </pre>\r
- Where M is in the range -9 through +9\r
- <p>\r
- If M<0 then A>=B must be true, so the result is always\r
- non-negative.\r
- \r
- Leading zeros are not removed after a subtraction. The result is\r
- either the same length as the longer of A and B, or 1 longer than\r
- that (if a carry occurred).\r
- \r
- A is not altered unless Arg6 is 1.\r
- B is never altered.\r
- \r
- Arg1 is A\r
- Arg2 is A length to use (if longer than A, pad with 0's)\r
- Arg3 is B\r
- Arg4 is B length to use (if longer than B, pad with 0's)\r
- Arg5 is M, the multiplier\r
- Arg6 is 1 if A can be used to build the result (if it fits)\r
- \r
- This routine is severely performance-critical; *any* change here\r
- must be measured (timed) to assure no performance degradation.\r
- */\r
- // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)\r
- // 1997.10.05 -- changed to byte arrays (from char arrays)\r
- // 1998.07.01 -- changed to allow destructive reuse of LHS\r
- // 1998.07.01 -- changed to allow virtual lengths for the arrays\r
- // 1998.12.29 -- use lookaside for digit/carry calculation\r
- // 1999.08.07 -- avoid multiply when mult=1, and make db an int\r
- // 1999.12.22 -- special case m=-1, also drop 0 special case\r
- \r
- private static final byte[] byteaddsub(byte a[],int avlen,byte b[],int bvlen,int m,boolean reuse){\r
- int alength;\r
- int blength;\r
- int ap;\r
- int bp;\r
- int maxarr;\r
- byte reb[];\r
- boolean quickm;\r
- int digit;\r
- int op=0;\r
- int dp90=0;\r
- byte newarr[];\r
- int i=0;\r
- \r
- \r
- \r
- \r
- // We'll usually be right if we assume no carry\r
- alength=a.length; // physical lengths\r
- blength=b.length; // ..\r
- ap=avlen-1; // -> final (rightmost) digit\r
- bp=bvlen-1; // ..\r
- maxarr=bp;\r
- if (maxarr<ap) \r
- maxarr=ap;\r
- reb=(byte[])null; // result byte array\r
- if (reuse) \r
- if ((maxarr+1)==alength) \r
- reb=a; // OK to reuse A\r
- if (reb==null) \r
- reb=new byte[maxarr+1]; // need new array\r
- \r
- quickm=false; // 1 if no multiply needed\r
- if (m==1) \r
- quickm=true; // most common\r
- else \r
- if (m==(-1)) \r
- quickm=true; // also common\r
- \r
- digit=0; // digit, with carry or borrow\r
- {op=maxarr;op:for(;op>=0;op--){\r
- if (ap>=0) \r
- {\r
- if (ap<alength) \r
- digit=digit+a[ap]; // within A\r
- ap--;\r
- }\r
- if (bp>=0) \r
- {\r
- if (bp<blength) \r
- { // within B\r
- if (quickm) \r
- {\r
- if (m>0) \r
- digit=digit+b[bp]; // most common\r
- else \r
- digit=digit-b[bp]; // also common\r
- }\r
- else \r
- digit=digit+(b[bp]*m);\r
- }\r
- bp--;\r
- }\r
- /* result so far (digit) could be -90 through 99 */\r
- if (digit<10) \r
- if (digit>=0) \r
- {do{ // 0-9\r
- reb[op]=(byte)digit;\r
- digit=0; // no carry\r
- continue op;\r
- }while(false);}/*quick*/\r
- dp90=digit+90;\r
- reb[op]=bytedig[dp90]; // this digit\r
- digit=bytecar[dp90]; // carry or borrow\r
- }\r
- }/*op*/\r
- \r
- if (digit==0) \r
- return reb; // no carry\r
- // following line will become an Assert, later\r
- // if digit<0 then signal ArithmeticException("internal.error ["digit"]")\r
- \r
- /* We have carry -- need to make space for the extra digit */\r
- newarr=(byte[])null;\r
- if (reuse) \r
- if ((maxarr+2)==a.length) \r
- newarr=a; // OK to reuse A\r
- if (newarr==null) \r
- newarr=new byte[maxarr+2];\r
- newarr[0]=(byte)digit; // the carried digit ..\r
- // .. and all the rest [use local loop for short numbers]\r
- if (maxarr<10) \r
- {int $24=maxarr+1;i=0;for(;$24>0;$24--,i++){\r
- newarr[i+1]=reb[i];\r
- }\r
- }/*i*/\r
- else \r
- java.lang.System.arraycopy((java.lang.Object)reb,0,(java.lang.Object)newarr,1,maxarr+1);\r
- return newarr;\r
- }\r
-\r
- /* <sgml> Initializer for digit array properties (lookaside). </sgml>\r
- Returns the digit array, and initializes the carry array. */\r
- \r
- private static final byte[] diginit(){\r
- byte work[];\r
- int op=0;\r
- int digit=0;\r
- work=new byte[(90+99)+1];\r
- {op=0;op:for(;op<=(90+99);op++){\r
- digit=op-90;\r
- if (digit>=0) \r
- {\r
- work[op]=(byte)(digit%10);\r
- bytecar[op]=(byte)(digit/10); // calculate carry\r
- continue op;\r
- }\r
- // borrowing...\r
- digit=digit+100; // yes, this is right [consider -50]\r
- work[op]=(byte)(digit%10);\r
- bytecar[op]=(byte)((digit/10)-10); // calculate borrow [NB: - after %]\r
- }\r
- }/*op*/\r
- return work;\r
- }\r
-\r
- /* <sgml> Create a copy of BigDecimal object for local use.\r
- <p>This does NOT make a copy of the mantissa array.\r
- </sgml>\r
- Arg1 is the BigDecimal to clone (non-null)\r
- */\r
- \r
- private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec){\r
- com.ibm.icu.math.BigDecimal copy;\r
- copy=new com.ibm.icu.math.BigDecimal();\r
- copy.ind=dec.ind;\r
- copy.exp=dec.exp;\r
- copy.form=dec.form;\r
- copy.mant=dec.mant;\r
- return copy;\r
- }\r
-\r
- /* <sgml> Check one or two numbers for lost digits. </sgml>\r
- Arg1 is RHS (or null, if none)\r
- Arg2 is current DIGITS setting\r
- returns quietly or throws an exception */\r
- \r
- private void checkdigits(com.ibm.icu.math.BigDecimal rhs,int dig){\r
- if (dig==0) \r
- return; // don't check if digits=0\r
- // first check lhs...\r
- if (this.mant.length>dig) \r
- if ((!(allzero(this.mant,dig)))) \r
- throw new java.lang.ArithmeticException("Too many digits:"+" "+this.toString());\r
- if (rhs==null) \r
- return; // monadic\r
- if (rhs.mant.length>dig) \r
- if ((!(allzero(rhs.mant,dig)))) \r
- throw new java.lang.ArithmeticException("Too many digits:"+" "+rhs.toString());\r
- }\r
-\r
- /* <sgml> Round to specified digits, if necessary. </sgml>\r
- Arg1 is requested MathContext [with length and rounding mode]\r
- returns this, for convenience */\r
- \r
- private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set){\r
- return round(set.digits,set.roundingMode);\r
- }\r
-\r
- /* <sgml> Round to specified digits, if necessary.\r
- Arg1 is requested length (digits to round to)\r
- [may be <=0 when called from format, dodivide, etc.]\r
- Arg2 is rounding mode\r
- returns this, for convenience\r
- \r
- ind and exp are adjusted, but not cleared for a mantissa of zero\r
- \r
- The length of the mantissa returned will be Arg1, except when Arg1\r
- is 0, in which case the returned mantissa length will be 1.\r
- </sgml>\r
- */\r
- \r
- private com.ibm.icu.math.BigDecimal round(int len,int mode){\r
- int adjust;\r
- int sign;\r
- byte oldmant[];\r
- boolean reuse=false;\r
- byte first=0;\r
- int increment;\r
- byte newmant[]=null;\r
- adjust=mant.length-len;\r
- if (adjust<=0) \r
- return this; // nowt to do\r
- \r
- exp=exp+adjust; // exponent of result\r
- sign=(int)ind; // save [assumes -1, 0, 1]\r
- oldmant=mant; // save\r
- if (len>0) \r
- {\r
- // remove the unwanted digits\r
- mant=new byte[len];\r
- java.lang.System.arraycopy((java.lang.Object)oldmant,0,(java.lang.Object)mant,0,len);\r
- reuse=true; // can reuse mantissa\r
- first=oldmant[len]; // first of discarded digits\r
- }\r
- else \r
- {/* len<=0 */\r
- mant=ZERO.mant;\r
- ind=iszero;\r
- reuse=false; // cannot reuse mantissa\r
- if (len==0) \r
- first=oldmant[0];\r
- else \r
- first=(byte)0; // [virtual digit]\r
- }\r
- \r
- // decide rounding adjustment depending on mode, sign, and discarded digits\r
- increment=0; // bumper\r
- {do{/*select*/\r
- if (mode==ROUND_HALF_UP)\r
- { // default first [most common]\r
- if (first>=5) \r
- increment=sign;\r
- }\r
- else if (mode==ROUND_UNNECESSARY)\r
- { // default for setScale()\r
- // discarding any non-zero digits is an error\r
- if ((!(allzero(oldmant,len)))) \r
- throw new java.lang.ArithmeticException("Rounding necessary");\r
- }\r
- else if (mode==ROUND_HALF_DOWN)\r
- { // 0.5000 goes down\r
- if (first>5) \r
- increment=sign;\r
- else \r
- if (first==5) \r
- if ((!(allzero(oldmant,len+1)))) \r
- increment=sign;\r
- }\r
- else if (mode==ROUND_HALF_EVEN)\r
- { // 0.5000 goes down if left digit even\r
- if (first>5) \r
- increment=sign;\r
- else \r
- if (first==5) \r
- {\r
- if ((!(allzero(oldmant,len+1)))) \r
- increment=sign;\r
- else /* 0.5000 */\r
- if ((((mant[mant.length-1])%2))==1) \r
- increment=sign;\r
- }\r
- }\r
- else if (mode==ROUND_DOWN){\r
- // never increment\r
- }else if (mode==ROUND_UP)\r
- { // increment if discarded non-zero\r
- if ((!(allzero(oldmant,len)))) \r
- increment=sign;\r
- }\r
- else if (mode==ROUND_CEILING)\r
- { // more positive\r
- if (sign>0) \r
- if ((!(allzero(oldmant,len)))) \r
- increment=sign;\r
- }\r
- else if (mode==ROUND_FLOOR)\r
- { // more negative\r
- if (sign<0) \r
- if ((!(allzero(oldmant,len)))) \r
- increment=sign;\r
- }\r
- else{\r
- throw new java.lang.IllegalArgumentException("Bad round value:"+" "+mode);\r
- }\r
- }while(false);}/*modes*/\r
- \r
- if (increment!=0) \r
- {do{\r
- if (ind==iszero) \r
- {\r
- // we must not subtract from 0, but result is trivial anyway\r
- mant=ONE.mant;\r
- ind=(byte)increment;\r
- }\r
- else \r
- {\r
- // mantissa is non-0; we can safely add or subtract 1\r
- if (ind==isneg) \r
- increment=(int)-increment;\r
- newmant=byteaddsub(mant,mant.length,ONE.mant,1,increment,reuse);\r
- if (newmant.length>mant.length) \r
- { // had a carry\r
- // drop rightmost digit and raise exponent\r
- exp++;\r
- // mant is already the correct length\r
- java.lang.System.arraycopy((java.lang.Object)newmant,0,(java.lang.Object)mant,0,mant.length);\r
- }\r
- else \r
- mant=newmant;\r
- }\r
- }while(false);}/*bump*/\r
- // rounding can increase exponent significantly\r
- if (exp>MaxExp) \r
- throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+exp);\r
- return this;\r
- }\r
-\r
- /* <sgml> Test if rightmost digits are all 0.\r
- Arg1 is a mantissa array to test\r
- Arg2 is the offset of first digit to check\r
- [may be negative; if so, digits to left are 0's]\r
- returns 1 if all the digits starting at Arg2 are 0\r
- \r
- Arg2 may be beyond array bounds, in which case 1 is returned\r
- </sgml> */\r
- \r
- private static final boolean allzero(byte array[],int start){\r
- int i=0;\r
- if (start<0) \r
- start=0;\r
- {int $25=array.length-1;i=start;for(;i<=$25;i++){\r
- if (array[i]!=0) \r
- return false;\r
- }\r
- }/*i*/\r
- return true;\r
- }\r
-\r
- /* <sgml> Carry out final checks and canonicalization\r
- <p>\r
- This finishes off the current number by:\r
- 1. Rounding if necessary (NB: length includes leading zeros)\r
- 2. Stripping trailing zeros (if requested and \PLAIN)\r
- 3. Stripping leading zeros (always)\r
- 4. Selecting exponential notation (if required)\r
- 5. Converting a zero result to just '0' (if \PLAIN)\r
- In practice, these operations overlap and share code.\r
- It always sets form.\r
- </sgml>\r
- Arg1 is requested MathContext (length to round to, trigger, and FORM)\r
- Arg2 is 1 if trailing insignificant zeros should be removed after\r
- round (for division, etc.), provided that set.form isn't PLAIN.\r
- returns this, for convenience\r
- */\r
- \r
- private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set,boolean strip){\r
- int d=0;\r
- int i=0;\r
- byte newmant[]=null;\r
- int mag=0;\r
- int sig=0;\r
- /* Round if mantissa too long and digits requested */\r
- if (set.digits!=0) \r
- if (this.mant.length>set.digits) \r
- this.round(set);\r
- \r
- /* If strip requested (and standard formatting), remove\r
- insignificant trailing zeros. */\r
- if (strip) \r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN) \r
- {\r
- d=this.mant.length;\r
- /* see if we need to drop any trailing zeros */\r
- {i=d-1;i:for(;i>=1;i--){\r
- if (this.mant[i]!=0) \r
- break i;\r
- d--;\r
- exp++;\r
- }\r
- }/*i*/\r
- if (d<this.mant.length) \r
- {/* need to reduce */\r
- newmant=new byte[d];\r
- java.lang.System.arraycopy((java.lang.Object)this.mant,0,(java.lang.Object)newmant,0,d);\r
- this.mant=newmant;\r
- }\r
- }\r
- \r
- form=(byte)com.ibm.icu.math.MathContext.PLAIN; // preset\r
- \r
- /* Now check for leading- and all- zeros in mantissa */\r
- {int $26=this.mant.length;i=0;for(;$26>0;$26--,i++){\r
- if (this.mant[i]!=0) \r
- {\r
- // non-0 result; ind will be correct\r
- // remove leading zeros [e.g., after subtract]\r
- if (i>0) \r
- {do{\r
- newmant=new byte[this.mant.length-i];\r
- java.lang.System.arraycopy((java.lang.Object)this.mant,i,(java.lang.Object)newmant,0,this.mant.length-i);\r
- this.mant=newmant;\r
- }while(false);}/*delead*/\r
- // now determine form if not PLAIN\r
- mag=exp+mant.length;\r
- if (mag>0) \r
- { // most common path\r
- if (mag>set.digits) \r
- if (set.digits!=0) \r
- form=(byte)set.form;\r
- if ((mag-1)<=MaxExp) \r
- return this; // no overflow; quick return\r
- }\r
- else \r
- if (mag<(-5)) \r
- form=(byte)set.form;\r
- /* check for overflow */\r
- mag--;\r
- if ((mag<MinExp)|(mag>MaxExp)) \r
- {overflow:do{\r
- // possible reprieve if form is engineering\r
- if (form==com.ibm.icu.math.MathContext.ENGINEERING) \r
- {\r
- sig=mag%3; // leftover\r
- if (sig<0) \r
- sig=3+sig; // negative exponent\r
- mag=mag-sig; // exponent to use\r
- // 1999.06.29: second test here must be MaxExp\r
- if (mag>=MinExp) \r
- if (mag<=MaxExp) \r
- break overflow;\r
- }\r
- throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+mag);\r
- }while(false);}/*overflow*/\r
- return this;\r
- }\r
- }\r
- }/*i*/\r
- \r
- // Drop through to here only if mantissa is all zeros\r
- ind=iszero;\r
- {/*select*/\r
- if (set.form!=com.ibm.icu.math.MathContext.PLAIN)\r
- exp=0; // standard result; go to '0'\r
- else if (exp>0)\r
- exp=0; // +ve exponent also goes to '0'\r
- else{\r
- // a plain number with -ve exponent; preserve and check exponent\r
- if (exp<MinExp) \r
- throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+exp);\r
- }\r
- }\r
- mant=ZERO.mant; // canonical mantissa\r
- return this;\r
- }\r
- }\r
+//##header J2SE15
+/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
+/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
+package com.ibm.icu.math;
+import java.math.BigInteger;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.lang.UCharacter;
+
+/* ------------------------------------------------------------------ */
+/* BigDecimal -- Decimal arithmetic for Java */
+/* ------------------------------------------------------------------ */
+/* Copyright IBM Corporation, 1996-2009. All Rights Reserved. */
+/* */
+/* The BigDecimal class provides immutable arbitrary-precision */
+/* floating point (including integer) decimal numbers. */
+/* */
+/* As the numbers are decimal, there is an exact correspondence */
+/* between an instance of a BigDecimal object and its String */
+/* representation; the BigDecimal class provides direct conversions */
+/* to and from String and character array objects, and well as */
+/* conversions to and from the Java primitive types (which may not */
+/* be exact). */
+/* ------------------------------------------------------------------ */
+/* Notes: */
+/* */
+/* 1. A BigDecimal object is never changed in value once constructed; */
+/* this avoids the need for locking. Note in particular that the */
+/* mantissa array may be shared between many BigDecimal objects, */
+/* so that once exposed it must not be altered. */
+/* */
+/* 2. This class looks at MathContext class fields directly (for */
+/* performance). It must not and does not change them. */
+/* */
+/* 3. Exponent checking is delayed until finish(), as we know */
+/* intermediate calculations cannot cause 31-bit overflow. */
+/* [This assertion depends on MAX_DIGITS in MathContext.] */
+/* */
+/* 4. Comments for the public API now follow the javadoc conventions. */
+/* The NetRexx -comments option is used to pass these comments */
+/* through to the generated Java code (with -format, if desired). */
+/* */
+/* 5. System.arraycopy is faster than explicit loop as follows */
+/* Mean length 4: equal */
+/* Mean length 8: x2 */
+/* Mean length 16: x3 */
+/* Mean length 24: x4 */
+/* From prior experience, we expect mean length a little below 8, */
+/* but arraycopy is still the one to use, in general, until later */
+/* measurements suggest otherwise. */
+/* */
+/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370 */
+/* assembler code implementation of the algorithms below; it is */
+/* now called IXXRCN and is available with the OS/390 and VM/ESA */
+/* operating systems. */
+/* ------------------------------------------------------------------ */
+/* Change History: */
+/* 1997.09.02 Initial version (derived from netrexx.lang classes) */
+/* 1997.09.12 Add lostDigits checking */
+/* 1997.10.06 Change mantissa to a byte array */
+/* 1997.11.22 Rework power [did not prepare arguments, etc.] */
+/* 1997.12.13 multiply did not prepare arguments */
+/* 1997.12.14 add did not prepare and align arguments correctly */
+/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle */
+/* 1998.05.21 adjust remainder operator finalization */
+/* 1998.06.04 rework to pass MathContext to finish() and round() */
+/* 1998.06.06 change format to use round(); support rounding modes */
+/* 1998.06.25 rename to BigDecimal and begin merge */
+/* zero can now have trailing zeros (i.e., exp\=0) */
+/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger */
+/* unscaledValue, valueof */
+/* 1998.07.01 improve byteaddsub to allow array reuse, etc. */
+/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32] */
+/* 1998.07.07 scaled division [divide(BigDecimal, int, int)] */
+/* 1998.07.08 setScale, faster equals */
+/* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
+/* 1998.10.12 change package to com.ibm.icu.math */
+/* 1998.12.14 power operator no longer rounds RHS [to match ANSI] */
+/* add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
+/* 1998.12.29 improve byteaddsub by using table lookup */
+/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
+/* 1999.02.05 cleaner code for BigDecimal(char[]) */
+/* 1999.02.06 add javadoc comments */
+/* 1999.02.11 format() changed from 7 to 2 method form */
+/* 1999.03.05 null pointer checking is no longer explicit */
+/* 1999.03.05 simplify; changes from discussion with J. Bloch: */
+/* null no longer permitted for MathContext; drop boolean, */
+/* byte, char, float, short constructor, deprecate double */
+/* constructor, no blanks in string constructor, add */
+/* offset and length version of char[] constructor; */
+/* add valueOf(double); drop booleanValue, charValue; */
+/* add ...Exact versions of remaining convertors */
+/* 1999.03.13 add toBigIntegerExact */
+/* 1999.03.13 1.00 release to IBM Centre for Java Technology */
+/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic */
+/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits */
+/* 1999.07.03 1.03 lost digits should not be checked if digits=0 */
+/* 1999.07.06 lost digits Exception message changed */
+/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic) */
+/* 1999.07.17 improve messages from pow method */
+/* 1999.08.08 performance tweaks */
+/* 1999.08.15 fastpath in multiply */
+/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555] */
+/* 1999.12.22 1.06 remove multiply fastpath, and improve performance */
+/* 2000.01.01 copyright update [Y2K has arrived] */
+/* 2000.06.18 1.08 no longer deprecate BigDecimal(double) */
+/* ------------------------------------------------------------------ */
+
+
+
+
+
+/**
+ * The <code>BigDecimal</code> class implements immutable
+ * arbitrary-precision decimal numbers. The methods of the
+ * <code>BigDecimal</code> class provide operations for fixed and
+ * floating point arithmetic, comparison, format conversions, and
+ * hashing.
+ * <p>
+ * As the numbers are decimal, there is an exact correspondence between
+ * an instance of a <code>BigDecimal</code> object and its
+ * <code>String</code> representation; the <code>BigDecimal</code> class
+ * provides direct conversions to and from <code>String</code> and
+ * character array (<code>char[]</code>) objects, as well as conversions
+ * to and from the Java primitive types (which may not be exact) and
+ * <code>BigInteger</code>.
+ * <p>
+ * In the descriptions of constructors and methods in this documentation,
+ * the value of a <code>BigDecimal</code> number object is shown as the
+ * result of invoking the <code>toString()</code> method on the object.
+ * The internal representation of a decimal number is neither defined
+ * nor exposed, and is not permitted to affect the result of any
+ * operation.
+ * <p>
+ * The floating point arithmetic provided by this class is defined by
+ * the ANSI X3.274-1996 standard, and is also documented at
+ * <code>http://www2.hursley.ibm.com/decimal</code>
+ * <br><i>[This URL will change.]</i>
+ *
+ * <h3>Operator methods</h3>
+ * <p>
+ * Operations on <code>BigDecimal</code> numbers are controlled by a
+ * {@link MathContext} object, which provides the context (precision and
+ * other information) for the operation. Methods that can take a
+ * <code>MathContext</code> parameter implement the standard arithmetic
+ * operators for <code>BigDecimal</code> objects and are known as
+ * <i>operator methods</i>. The default settings provided by the
+ * constant {@link MathContext#DEFAULT} (<code>digits=9,
+ * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>)
+ * perform general-purpose floating point arithmetic to nine digits of
+ * precision. The <code>MathContext</code> parameter must not be
+ * <code>null</code>.
+ * <p>
+ * Each operator method also has a version provided which does
+ * not take a <code>MathContext</code> parameter. For this version of
+ * each method, the context settings used are <code>digits=0,
+ * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>;
+ * these settings perform fixed point arithmetic with unlimited
+ * precision, as defined for the original BigDecimal class in Java 1.1
+ * and Java 1.2.
+ * <p>
+ * For monadic operators, only the optional <code>MathContext</code>
+ * parameter is present; the operation acts upon the current object.
+ * <p>
+ * For dyadic operators, a <code>BigDecimal</code> parameter is always
+ * present; it must not be <code>null</code>.
+ * The operation acts with the current object being the left-hand operand
+ * and the <code>BigDecimal</code> parameter being the right-hand operand.
+ * <p>
+ * For example, adding two <code>BigDecimal</code> objects referred to
+ * by the names <code>award</code> and <code>extra</code> could be
+ * written as any of:
+ * <p><code>
+ * award.add(extra)
+ * <br>award.add(extra, MathContext.DEFAULT)
+ * <br>award.add(extra, acontext)
+ * </code>
+ * <p>
+ * (where <code>acontext</code> is a <code>MathContext</code> object),
+ * which would return a <code>BigDecimal</code> object whose value is
+ * the result of adding <code>award</code> and <code>extra</code> under
+ * the appropriate context settings.
+ * <p>
+ * When a <code>BigDecimal</code> operator method is used, a set of
+ * rules define what the result will be (and, by implication, how the
+ * result would be represented as a character string).
+ * These rules are defined in the BigDecimal arithmetic documentation
+ * (see the URL above), but in summary:
+ * <ul>
+ * <li>Results are normally calculated with up to some maximum number of
+ * significant digits.
+ * For example, if the <code>MathContext</code> parameter for an operation
+ * were <code>MathContext.DEFAULT</code> then the result would be
+ * rounded to 9 digits; the division of 2 by 3 would then result in
+ * 0.666666667.
+ * <br>
+ * You can change the default of 9 significant digits by providing the
+ * method with a suitable <code>MathContext</code> object. This lets you
+ * calculate using as many digits as you need -- thousands, if necessary.
+ * Fixed point (scaled) arithmetic is indicated by using a
+ * <code>digits</code> setting of 0 (or omitting the
+ * <code>MathContext</code> parameter).
+ * <br>
+ * Similarly, you can change the algorithm used for rounding from the
+ * default "classic" algorithm.
+ * <li>
+ * In standard arithmetic (that is, when the <code>form</code> setting
+ * is not <code>PLAIN</code>), a zero result is always expressed as the
+ * single digit <code>'0'</code> (that is, with no sign, decimal point,
+ * or exponent part).
+ * <li>
+ * Except for the division and power operators in standard arithmetic,
+ * trailing zeros are preserved (this is in contrast to binary floating
+ * point operations and most electronic calculators, which lose the
+ * information about trailing zeros in the fractional part of results).
+ * <br>
+ * So, for example:
+ * <p><code>
+ * new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40"
+ * <br>new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40"
+ * <br>new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80"
+ * <br>new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2"
+ * </code>
+ * <p>where the value on the right of the <code>=></code> would be the
+ * result of the operation, expressed as a <code>String</code>, and
+ * <code>def</code> (in this and following examples) refers to
+ * <code>MathContext.DEFAULT</code>).
+ * This preservation of trailing zeros is desirable for most
+ * calculations (including financial calculations).
+ * If necessary, trailing zeros may be easily removed using division by 1.
+ * <li>
+ * In standard arithmetic, exponential form is used for a result
+ * depending on its value and the current setting of <code>digits</code>
+ * (the default is 9 digits).
+ * If the number of places needed before the decimal point exceeds the
+ * <code>digits</code> setting, or the absolute value of the number is
+ * less than <code>0.000001</code>, then the number will be expressed in
+ * exponential notation; thus
+ * <p><code>
+ * new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
+ * </code>
+ * <p>results in <code>1E+12</code> instead of
+ * <code>1000000000000</code>, and
+ * <p><code>
+ * new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
+ * </code>
+ * <p>results in <code>3.33333333E-11</code> instead of
+ * <code>0.0000000000333333333</code>.
+ * <p>
+ * The form of the exponential notation (scientific or engineering) is
+ * determined by the <code>form</code> setting.
+ * <eul>
+ * <p>
+ * The names of methods in this class follow the conventions established
+ * by <code>java.lang.Number</code>, <code>java.math.BigInteger</code>,
+ * and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
+ *
+ * @see MathContext
+ * @author Mike Cowlishaw
+ * @stable ICU 2.0
+ */
+
+public class BigDecimal extends java.lang.Number implements java.io.Serializable,java.lang.Comparable{
+ //private static final java.lang.String $0="BigDecimal.nrx";
+
+
+
+ /* ----- Constants ----- */
+ /* properties constant public */ // useful to others
+ /**
+ * The <code>BigDecimal</code> constant "0".
+ *
+ * @see #ONE
+ * @see #TEN
+ * @stable ICU 2.0
+ */
+ public static final com.ibm.icu.math.BigDecimal ZERO=new com.ibm.icu.math.BigDecimal((long)0); // use long as we want the int constructor
+ // .. to be able to use this, for speed
+
+ /**
+ * The <code>BigDecimal</code> constant "1".
+ *
+ * @see #TEN
+ * @see #ZERO
+ * @stable ICU 2.0
+ */
+ public static final com.ibm.icu.math.BigDecimal ONE=new com.ibm.icu.math.BigDecimal((long)1); // use long as we want the int constructor
+ // .. to be able to use this, for speed
+
+ /**
+ * The <code>BigDecimal</code> constant "10".
+ *
+ * @see #ONE
+ * @see #ZERO
+ * @stable ICU 2.0
+ */
+ public static final com.ibm.icu.math.BigDecimal TEN=new com.ibm.icu.math.BigDecimal(10);
+
+ // the rounding modes (copied here for upwards compatibility)
+ /**
+ * Rounding mode to round to a more positive number.
+ * @see MathContext#ROUND_CEILING
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_CEILING=com.ibm.icu.math.MathContext.ROUND_CEILING;
+
+ /**
+ * Rounding mode to round towards zero.
+ * @see MathContext#ROUND_DOWN
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_DOWN=com.ibm.icu.math.MathContext.ROUND_DOWN;
+
+ /**
+ * Rounding mode to round to a more negative number.
+ * @see MathContext#ROUND_FLOOR
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_FLOOR=com.ibm.icu.math.MathContext.ROUND_FLOOR;
+
+ /**
+ * Rounding mode to round to nearest neighbor, where an equidistant
+ * value is rounded down.
+ * @see MathContext#ROUND_HALF_DOWN
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_HALF_DOWN=com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;
+
+ /**
+ * Rounding mode to round to nearest neighbor, where an equidistant
+ * value is rounded to the nearest even neighbor.
+ * @see MathContext#ROUND_HALF_EVEN
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_HALF_EVEN=com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;
+
+ /**
+ * Rounding mode to round to nearest neighbor, where an equidistant
+ * value is rounded up.
+ * @see MathContext#ROUND_HALF_UP
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_HALF_UP=com.ibm.icu.math.MathContext.ROUND_HALF_UP;
+
+ /**
+ * Rounding mode to assert that no rounding is necessary.
+ * @see MathContext#ROUND_UNNECESSARY
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_UNNECESSARY=com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;
+
+ /**
+ * Rounding mode to round away from zero.
+ * @see MathContext#ROUND_UP
+ * @stable ICU 2.0
+ */
+ public static final int ROUND_UP=com.ibm.icu.math.MathContext.ROUND_UP;
+
+ /* properties constant private */ // locals
+ private static final byte ispos=1; // ind: indicates positive (must be 1)
+ private static final byte iszero=0; // ind: indicates zero (must be 0)
+ private static final byte isneg=-1; // ind: indicates negative (must be -1)
+ // [later could add NaN, +/- infinity, here]
+
+ private static final int MinExp=-999999999; // minimum exponent allowed
+ private static final int MaxExp=999999999; // maximum exponent allowed
+ private static final int MinArg=-999999999; // minimum argument integer
+ private static final int MaxArg=999999999; // maximum argument integer
+
+ private static final com.ibm.icu.math.MathContext plainMC=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math
+
+ /* properties constant private unused */ // present but not referenced
+
+ // Serialization version
+ private static final long serialVersionUID=8245355804974198832L;
+
+ //private static final java.lang.String copyright=" Copyright (c) IBM Corporation 1996, 2000. All rights reserved. ";
+
+ /* properties static private */
+ // Precalculated constant arrays (used by byteaddsub)
+ private static byte bytecar[]=new byte[(90+99)+1]; // carry/borrow array
+ private static byte bytedig[]=diginit(); // next digit array
+
+ /* ----- Instance properties [all private and immutable] ----- */
+ /* properties private */
+
+ /**
+ * The indicator. This may take the values:
+ * <ul>
+ * <li>ispos -- the number is positive
+ * <li>iszero -- the number is zero
+ * <li>isneg -- the number is negative
+ * </ul>
+ *
+ * @serial
+ */
+ private byte ind; // assumed undefined
+ // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
+ // We only need two bits for this, but use a byte [also permits
+ // smooth future extension].
+
+ /**
+ * The formatting style. This may take the values:
+ * <ul>
+ * <li>MathContext.PLAIN -- no exponent needed
+ * <li>MathContext.SCIENTIFIC -- scientific notation required
+ * <li>MathContext.ENGINEERING -- engineering notation required
+ * </ul>
+ * <p>
+ * This property is an optimization; it allows us to defer number
+ * layout until it is actually needed as a string, hence avoiding
+ * unnecessary formatting.
+ *
+ * @serial
+ */
+ private byte form=(byte)com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
+ // We only need two bits for this, at present, but use a byte
+ // [again, to allow for smooth future extension]
+
+ /**
+ * The value of the mantissa.
+ * <p>
+ * Once constructed, this may become shared between several BigDecimal
+ * objects, so must not be altered.
+ * <p>
+ * For efficiency (speed), this is a byte array, with each byte
+ * taking a value of 0 -> 9.
+ * <p>
+ * If the first byte is 0 then the value of the number is zero (and
+ * mant.length=1, except when constructed from a plain number, for
+ * example, 0.000).
+ *
+ * @serial
+ */
+ private byte mant[]; // assumed null
+
+ /**
+ * The exponent.
+ * <p>
+ * For fixed point arithmetic, scale is <code>-exp</code>, and can
+ * apply to zero.
+ *
+ * Note that this property can have a value less than MinExp when
+ * the mantissa has more than one digit.
+ *
+ * @serial
+ */
+ private int exp;
+ // assumed 0
+
+ /* ---------------------------------------------------------------- */
+ /* Constructors */
+ /* ---------------------------------------------------------------- */
+
+//#if defined(FOUNDATION10)
+//#else
+ /**
+ * Constructs a <code>BigDecimal</code> object from a
+ * <code>java.math.BigDecimal</code>.
+ * <p>
+ * Constructs a <code>BigDecimal</code> as though the parameter had
+ * been represented as a <code>String</code> (using its
+ * <code>toString</code> method) and the
+ * {@link #BigDecimal(java.lang.String)} constructor had then been
+ * used.
+ * The parameter must not be <code>null</code>.
+ * <p>
+ * <i>(Note: this constructor is provided only in the
+ * <code>com.ibm.icu.math</code> version of the BigDecimal class.
+ * It would not be present in a <code>java.math</code> version.)</i>
+ *
+ * @param bd The <code>BigDecimal</code> to be translated.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(java.math.BigDecimal bd){
+ this(bd.toString());
+ return;}
+//#endif
+
+ /**
+ * Constructs a <code>BigDecimal</code> object from a
+ * <code>BigInteger</code>, with scale 0.
+ * <p>
+ * Constructs a <code>BigDecimal</code> which is the exact decimal
+ * representation of the <code>BigInteger</code>, with a scale of
+ * zero.
+ * The value of the <code>BigDecimal</code> is identical to the value
+ * of the <code>BigInteger</code>.
+ * The parameter must not be <code>null</code>.
+ * <p>
+ * The <code>BigDecimal</code> will contain only decimal digits,
+ * prefixed with a leading minus sign (hyphen) if the
+ * <code>BigInteger</code> is negative. A leading zero will be
+ * present only if the <code>BigInteger</code> is zero.
+ *
+ * @param bi The <code>BigInteger</code> to be converted.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(java.math.BigInteger bi){
+ this(bi.toString(10));
+ return;}
+ // exp remains 0
+
+ /**
+ * Constructs a <code>BigDecimal</code> object from a
+ * <code>BigInteger</code> and a scale.
+ * <p>
+ * Constructs a <code>BigDecimal</code> which is the exact decimal
+ * representation of the <code>BigInteger</code>, scaled by the
+ * second parameter, which may not be negative.
+ * The value of the <code>BigDecimal</code> is the
+ * <code>BigInteger</code> divided by ten to the power of the scale.
+ * The <code>BigInteger</code> parameter must not be
+ * <code>null</code>.
+ * <p>
+ * The <code>BigDecimal</code> will contain only decimal digits, (with
+ * an embedded decimal point followed by <code>scale</code> decimal
+ * digits if the scale is positive), prefixed with a leading minus
+ * sign (hyphen) if the <code>BigInteger</code> is negative. A
+ * leading zero will be present only if the <code>BigInteger</code> is
+ * zero.
+ *
+ * @param bi The <code>BigInteger</code> to be converted.
+ * @param scale The <code>int</code> specifying the scale.
+ * @throws NumberFormatException if the scale is negative.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(java.math.BigInteger bi,int scale){
+ this(bi.toString(10));
+ if (scale<0)
+ throw new java.lang.NumberFormatException("Negative scale:"+" "+scale);
+ exp=(int)-scale; // exponent is -scale
+ return;}
+
+ /**
+ * Constructs a <code>BigDecimal</code> object from an array of characters.
+ * <p>
+ * Constructs a <code>BigDecimal</code> as though a
+ * <code>String</code> had been constructed from the character array
+ * and the {@link #BigDecimal(java.lang.String)} constructor had then
+ * been used. The parameter must not be <code>null</code>.
+ * <p>
+ * Using this constructor is faster than using the
+ * <code>BigDecimal(String)</code> constructor if the string is
+ * already available in character array form.
+ *
+ * @param inchars The <code>char[]</code> array containing the number
+ * to be converted.
+ * @throws NumberFormatException if the parameter is not a valid
+ * number.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(char inchars[]){
+ this(inchars,0,inchars.length);
+ return;}
+
+ /**
+ * Constructs a <code>BigDecimal</code> object from an array of characters.
+ * <p>
+ * Constructs a <code>BigDecimal</code> as though a
+ * <code>String</code> had been constructed from the character array
+ * (or a subarray of that array) and the
+ * {@link #BigDecimal(java.lang.String)} constructor had then been
+ * used. The first parameter must not be <code>null</code>, and the
+ * subarray must be wholly contained within it.
+ * <p>
+ * Using this constructor is faster than using the
+ * <code>BigDecimal(String)</code> constructor if the string is
+ * already available within a character array.
+ *
+ * @param inchars The <code>char[]</code> array containing the number
+ * to be converted.
+ * @param offset The <code>int</code> offset into the array of the
+ * start of the number to be converted.
+ * @param length The <code>int</code> length of the number.
+ * @throws NumberFormatException if the parameter is not a valid
+ * number for any reason.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(char inchars[],int offset,int length){super();
+ boolean exotic;
+ boolean hadexp;
+ int d;
+ int dotoff;
+ int last;
+ int i=0;
+ char si=0;
+ boolean eneg=false;
+ int k=0;
+ int elen=0;
+ int j=0;
+ char sj=0;
+ int dvalue=0;
+ int mag=0;
+ // This is the primary constructor; all incoming strings end up
+ // here; it uses explicit (inline) parsing for speed and to avoid
+ // generating intermediate (temporary) objects of any kind.
+ // 1998.06.25: exponent form built only if E/e in string
+ // 1998.06.25: trailing zeros not removed for zero
+ // 1999.03.06: no embedded blanks; allow offset and length
+ if (length<=0)
+ bad(inchars); // bad conversion (empty string)
+ // [bad offset will raise array bounds exception]
+
+ /* Handle and step past sign */
+ ind=ispos; // assume positive
+ if (inchars[offset]==('-'))
+ {
+ length--;
+ if (length==0)
+ bad(inchars); // nothing after sign
+ ind=isneg;
+ offset++;
+ }
+ else
+ if (inchars[offset]==('+'))
+ {
+ length--;
+ if (length==0)
+ bad(inchars); // nothing after sign
+ offset++;
+ }
+
+ /* We're at the start of the number */
+ exotic=false; // have extra digits
+ hadexp=false; // had explicit exponent
+ d=0; // count of digits found
+ dotoff=-1; // offset where dot was found
+ last=-1; // last character of mantissa
+ {int $1=length;i=offset;i:for(;$1>0;$1--,i++){
+ si=inchars[i];
+ if (si>='0') // test for Arabic digit
+ if (si<='9')
+ {
+ last=i;
+ d++; // still in mantissa
+ continue i;
+ }
+ if (si=='.')
+ { // record and ignore
+ if (dotoff>=0)
+ bad(inchars); // two dots
+ dotoff=i-offset; // offset into mantissa
+ continue i;
+ }
+ if (si!='e')
+ if (si!='E')
+ { // expect an extra digit
+ if ((!(UCharacter.isDigit(si))))
+ bad(inchars); // not a number
+ // defer the base 10 check until later to avoid extra method call
+ exotic=true; // will need conversion later
+ last=i;
+ d++; // still in mantissa
+ continue i;
+ }
+ /* Found 'e' or 'E' -- now process explicit exponent */
+ // 1998.07.11: sign no longer required
+ if ((i-offset)>(length-2))
+ bad(inchars); // no room for even one digit
+ eneg=false;
+ if ((inchars[i+1])==('-'))
+ {
+ eneg=true;
+ k=i+2;
+ }
+ else
+ if ((inchars[i+1])==('+'))
+ k=i+2;
+ else
+ k=i+1;
+ // k is offset of first expected digit
+ elen=length-((k-offset)); // possible number of digits
+ if ((elen==0)|(elen>9))
+ bad(inchars); // 0 or more than 9 digits
+ {int $2=elen;j=k;for(;$2>0;$2--,j++){
+ sj=inchars[j];
+ if (sj<'0')
+ bad(inchars); // always bad
+ if (sj>'9')
+ { // maybe an exotic digit
+ if ((!(UCharacter.isDigit(sj))))
+ bad(inchars); // not a number
+ dvalue=UCharacter.digit(sj,10); // check base
+ if (dvalue<0)
+ bad(inchars); // not base 10
+ }
+ else
+ dvalue=((int)(sj))-((int)('0'));
+ exp=(exp*10)+dvalue;
+ }
+ }/*j*/
+ if (eneg)
+ exp=(int)-exp; // was negative
+ hadexp=true; // remember we had one
+ break i; // we are done
+ }
+ }/*i*/
+
+ /* Here when all inspected */
+ if (d==0)
+ bad(inchars); // no mantissa digits
+ if (dotoff>=0)
+ exp=(exp+dotoff)-d; // adjust exponent if had dot
+
+ /* strip leading zeros/dot (leave final if all 0's) */
+ {int $3=last-1;i=offset;i:for(;i<=$3;i++){
+ si=inchars[i];
+ if (si=='0')
+ {
+ offset++;
+ dotoff--;
+ d--;
+ }
+ else
+ if (si=='.')
+ {
+ offset++; // step past dot
+ dotoff--;
+ }
+ else
+ if (si<='9')
+ break i;/* non-0 */
+ else
+ {/* exotic */
+ if ((UCharacter.digit(si,10))!=0)
+ break i; // non-0 or bad
+ // is 0 .. strip like '0'
+ offset++;
+ dotoff--;
+ d--;
+ }
+ }
+ }/*i*/
+
+ /* Create the mantissa array */
+ mant=new byte[d]; // we know the length
+ j=offset; // input offset
+ if (exotic)
+ {do{ // slow: check for exotica
+ {int $4=d;i=0;for(;$4>0;$4--,i++){
+ if (i==dotoff)
+ j++; // at dot
+ sj=inchars[j];
+ if (sj<='9')
+ mant[i]=(byte)(((int)(sj))-((int)('0')));/* easy */
+ else
+ {
+ dvalue=UCharacter.digit(sj,10);
+ if (dvalue<0)
+ bad(inchars); // not a number after all
+ mant[i]=(byte)dvalue;
+ }
+ j++;
+ }
+ }/*i*/
+ }while(false);}/*exotica*/
+ else
+ {do{
+ {int $5=d;i=0;for(;$5>0;$5--,i++){
+ if (i==dotoff)
+ j++;
+ mant[i]=(byte)(((int)(inchars[j]))-((int)('0')));
+ j++;
+ }
+ }/*i*/
+ }while(false);}/*simple*/
+
+ /* Looks good. Set the sign indicator and form, as needed. */
+ // Trailing zeros are preserved
+ // The rule here for form is:
+ // If no E-notation, then request plain notation
+ // Otherwise act as though add(0,DEFAULT) and request scientific notation
+ // [form is already PLAIN]
+ if (mant[0]==0)
+ {
+ ind=iszero; // force to show zero
+ // negative exponent is significant (e.g., -3 for 0.000) if plain
+ if (exp>0)
+ exp=0; // positive exponent can be ignored
+ if (hadexp)
+ { // zero becomes single digit from add
+ mant=ZERO.mant;
+ exp=0;
+ }
+ }
+ else
+ { // non-zero
+ // [ind was set earlier]
+ // now determine form
+ if (hadexp)
+ {
+ form=(byte)com.ibm.icu.math.MathContext.SCIENTIFIC;
+ // 1999.06.29 check for overflow
+ mag=(exp+mant.length)-1; // true exponent in scientific notation
+ if ((mag<MinExp)|(mag>MaxExp))
+ bad(inchars);
+ }
+ }
+ // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
+ return;
+ }
+
+ /**
+ * Constructs a <code>BigDecimal</code> object directly from a
+ * <code>double</code>.
+ * <p>
+ * Constructs a <code>BigDecimal</code> which is the exact decimal
+ * representation of the 64-bit signed binary floating point
+ * parameter.
+ * <p>
+ * Note that this constructor it an exact conversion; it does not give
+ * the same result as converting <code>num</code> to a
+ * <code>String</code> using the <code>Double.toString()</code> method
+ * and then using the {@link #BigDecimal(java.lang.String)}
+ * constructor.
+ * To get that result, use the static {@link #valueOf(double)}
+ * method to construct a <code>BigDecimal</code> from a
+ * <code>double</code>.
+ *
+ * @param num The <code>double</code> to be converted.
+ * @throws NumberFormatException if the parameter is infinite or
+ * not a number.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(double num){
+ // 1999.03.06: use exactly the old algorithm
+ // 2000.01.01: note that this constructor does give an exact result,
+ // so perhaps it should not be deprecated
+ // 2000.06.18: no longer deprecated
+//#if defined(FOUNDATION10)
+//## this(String.valueOf(num));
+//#else
+ this((new java.math.BigDecimal(num)).toString());
+//#endif
+ return;}
+ /**
+ * Constructs a <code>BigDecimal</code> object directly from a
+ * <code>int</code>.
+ * <p>
+ * Constructs a <code>BigDecimal</code> which is the exact decimal
+ * representation of the 32-bit signed binary integer parameter.
+ * The <code>BigDecimal</code> will contain only decimal digits,
+ * prefixed with a leading minus sign (hyphen) if the parameter is
+ * negative.
+ * A leading zero will be present only if the parameter is zero.
+ *
+ * @param num The <code>int</code> to be converted.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(int num){super();
+ int mun;
+ int i=0;
+ // We fastpath commoners
+ if (num<=9)
+ if (num>=(-9))
+ {do{
+ // very common single digit case
+ {/*select*/
+ if (num==0)
+ {
+ mant=ZERO.mant;
+ ind=iszero;
+ }
+ else if (num==1)
+ {
+ mant=ONE.mant;
+ ind=ispos;
+ }
+ else if (num==(-1))
+ {
+ mant=ONE.mant;
+ ind=isneg;
+ }
+ else{
+ {
+ mant=new byte[1];
+ if (num>0)
+ {
+ mant[0]=(byte)num;
+ ind=ispos;
+ }
+ else
+ { // num<-1
+ mant[0]=(byte)((int)-num);
+ ind=isneg;
+ }
+ }
+ }
+ }
+ return;
+ }while(false);}/*singledigit*/
+
+ /* We work on negative numbers so we handle the most negative number */
+ if (num>0)
+ {
+ ind=ispos;
+ num=(int)-num;
+ }
+ else
+ ind=isneg;/* negative */ // [0 case already handled]
+ // [it is quicker, here, to pre-calculate the length with
+ // one loop, then allocate exactly the right length of byte array,
+ // then re-fill it with another loop]
+ mun=num; // working copy
+ {i=9;i:for(;;i--){
+ mun=mun/10;
+ if (mun==0)
+ break i;
+ }
+ }/*i*/
+ // i is the position of the leftmost digit placed
+ mant=new byte[10-i];
+ {i=(10-i)-1;i:for(;;i--){
+ mant[i]=(byte)-(((byte)(num%10)));
+ num=num/10;
+ if (num==0)
+ break i;
+ }
+ }/*i*/
+ return;
+ }
+
+ /**
+ * Constructs a <code>BigDecimal</code> object directly from a
+ * <code>long</code>.
+ * <p>
+ * Constructs a <code>BigDecimal</code> which is the exact decimal
+ * representation of the 64-bit signed binary integer parameter.
+ * The <code>BigDecimal</code> will contain only decimal digits,
+ * prefixed with a leading minus sign (hyphen) if the parameter is
+ * negative.
+ * A leading zero will be present only if the parameter is zero.
+ *
+ * @param num The <code>long</code> to be converted.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(long num){super();
+ long mun;
+ int i=0;
+ // Not really worth fastpathing commoners in this constructor [also,
+ // we use this to construct the static constants].
+ // This is much faster than: this(String.valueOf(num).toCharArray())
+ /* We work on negative num so we handle the most negative number */
+ if (num>0)
+ {
+ ind=ispos;
+ num=(long)-num;
+ }
+ else
+ if (num==0)
+ ind=iszero;
+ else
+ ind=isneg;/* negative */
+ mun=num;
+ {i=18;i:for(;;i--){
+ mun=mun/10;
+ if (mun==0)
+ break i;
+ }
+ }/*i*/
+ // i is the position of the leftmost digit placed
+ mant=new byte[19-i];
+ {i=(19-i)-1;i:for(;;i--){
+ mant[i]=(byte)-(((byte)(num%10)));
+ num=num/10;
+ if (num==0)
+ break i;
+ }
+ }/*i*/
+ return;
+ }
+
+ /**
+ * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
+ * <p>
+ * Constructs a <code>BigDecimal</code> from the parameter, which must
+ * not be <code>null</code> and must represent a valid <i>number</i>,
+ * as described formally in the documentation referred to
+ * {@link BigDecimal above}.
+ * <p>
+ * In summary, numbers in <code>String</code> form must have at least
+ * one digit, may have a leading sign, may have a decimal point, and
+ * exponential notation may be used. They follow conventional syntax,
+ * and may not contain blanks.
+ * <p>
+ * Some valid strings from which a <code>BigDecimal</code> might
+ * be constructed are:
+ * <pre>
+ * "0" -- Zero
+ * "12" -- A whole number
+ * "-76" -- A signed whole number
+ * "12.70" -- Some decimal places
+ * "+0.003" -- Plus sign is allowed
+ * "17." -- The same as 17
+ * ".5" -- The same as 0.5
+ * "4E+9" -- Exponential notation
+ * "0.73e-7" -- Exponential notation
+ * </pre>
+ * <p>
+ * (Exponential notation means that the number includes an optional
+ * sign and a power of ten following an '</code>E</code>' that
+ * indicates how the decimal point will be shifted. Thus the
+ * <code>"4E+9"</code> above is just a short way of writing
+ * <code>4000000000</code>, and the <code>"0.73e-7"</code> is short
+ * for <code>0.000000073</code>.)
+ * <p>
+ * The <code>BigDecimal</code> constructed from the String is in a
+ * standard form, with no blanks, as though the
+ * {@link #add(BigDecimal)} method had been used to add zero to the
+ * number with unlimited precision.
+ * If the string uses exponential notation (that is, includes an
+ * <code>e</code> or an <code>E</code>), then the
+ * <code>BigDecimal</code> number will be expressed in scientific
+ * notation (where the power of ten is adjusted so there is a single
+ * non-zero digit to the left of the decimal point); in this case if
+ * the number is zero then it will be expressed as the single digit 0,
+ * and if non-zero it will have an exponent unless that exponent would
+ * be 0. The exponent must fit in nine digits both before and after it
+ * is expressed in scientific notation.
+ * <p>
+ * Any digits in the parameter must be decimal; that is,
+ * <code>Character.digit(c, 10)</code> (where </code>c</code> is the
+ * character in question) would not return -1.
+ *
+ * @param string The <code>String</code> to be converted.
+ * @throws NumberFormatException if the parameter is not a valid
+ * number.
+ * @stable ICU 2.0
+ */
+
+ public BigDecimal(java.lang.String string){
+ this(string.toCharArray(),0,string.length());
+ return;}
+
+ /* <sgml> Make a default BigDecimal object for local use. </sgml> */
+
+ private BigDecimal(){super();
+ return;
+ }
+
+ /* ---------------------------------------------------------------- */
+ /* Operator methods [methods which take a context parameter] */
+ /* ---------------------------------------------------------------- */
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is the absolute
+ * value of this <code>BigDecimal</code>.
+ * <p>
+ * The same as {@link #abs(MathContext)}, where the context is
+ * <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will
+ * be <code>this.scale()</code>
+ *
+ * @return A <code>BigDecimal</code> whose value is the absolute
+ * value of this <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal abs(){
+ return this.abs(plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is the absolute value
+ * of this <code>BigDecimal</code>.
+ * <p>
+ * If the current object is zero or positive, then the same result as
+ * invoking the {@link #plus(MathContext)} method with the same
+ * parameter is returned.
+ * Otherwise, the same result as invoking the
+ * {@link #negate(MathContext)} method with the same parameter is
+ * returned.
+ *
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is the absolute
+ * value of this <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set){
+ if (this.ind==isneg)
+ return this.negate(set);
+ return this.plus(set);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this+rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #add(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * the maximum of the scales of the two operands.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the addition.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this+rhs</code>, using fixed point arithmetic.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs){
+ return this.add(rhs,plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
+ * <p>
+ * Implements the addition (<b><code>+</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the addition.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this+rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ com.ibm.icu.math.BigDecimal lhs;
+ int reqdig;
+ com.ibm.icu.math.BigDecimal res;
+ byte usel[];
+ int usellen;
+ byte user[];
+ int userlen;
+ int newlen=0;
+ int tlen=0;
+ int mult=0;
+ byte t[]=null;
+ int ia=0;
+ int ib=0;
+ int ea=0;
+ int eb=0;
+ byte ca=0;
+ byte cb=0;
+ /* determine requested digits and form */
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ lhs=this; // name for clarity and proxy
+
+ /* Quick exit for add floating 0 */
+ // plus() will optimize to return same object if possible
+ if (lhs.ind==0)
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ return rhs.plus(set);
+ if (rhs.ind==0)
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ return lhs.plus(set);
+
+ /* Prepare numbers (round, unless unlimited precision) */
+ reqdig=set.digits; // local copy (heavily used)
+ if (reqdig>0)
+ {
+ if (lhs.mant.length>reqdig)
+ lhs=clone(lhs).round(set);
+ if (rhs.mant.length>reqdig)
+ rhs=clone(rhs).round(set);
+ // [we could reuse the new LHS for result in this case]
+ }
+
+ res=new com.ibm.icu.math.BigDecimal(); // build result here
+
+ /* Now see how much we have to pad or truncate lhs or rhs in order
+ to align the numbers. If one number is much larger than the
+ other, then the smaller cannot affect the answer [but we may
+ still need to pad with up to DIGITS trailing zeros]. */
+ // Note sign may be 0 if digits (reqdig) is 0
+ // usel and user will be the byte arrays passed to the adder; we'll
+ // use them on all paths except quick exits
+ usel=lhs.mant;
+ usellen=lhs.mant.length;
+ user=rhs.mant;
+ userlen=rhs.mant.length;
+ {do{/*select*/
+ if (lhs.exp==rhs.exp)
+ {/* no padding needed */
+ // This is the most common, and fastest, path
+ res.exp=lhs.exp;
+ }
+ else if (lhs.exp>rhs.exp)
+ { // need to pad lhs and/or truncate rhs
+ newlen=(usellen+lhs.exp)-rhs.exp;
+ /* If, after pad, lhs would be longer than rhs by digits+1 or
+ more (and digits>0) then rhs cannot affect answer, so we only
+ need to pad up to a length of DIGITS+1. */
+ if (newlen>=((userlen+reqdig)+1))
+ if (reqdig>0)
+ {
+ // LHS is sufficient
+ res.mant=usel;
+ res.exp=lhs.exp;
+ res.ind=lhs.ind;
+ if (usellen<reqdig)
+ { // need 0 padding
+ res.mant=extend(lhs.mant,reqdig);
+ res.exp=res.exp-((reqdig-usellen));
+ }
+ return res.finish(set,false);
+ }
+ // RHS may affect result
+ res.exp=rhs.exp; // expected final exponent
+ if (newlen>(reqdig+1))
+ if (reqdig>0)
+ {
+ // LHS will be max; RHS truncated
+ tlen=(newlen-reqdig)-1; // truncation length
+ userlen=userlen-tlen;
+ res.exp=res.exp+tlen;
+ newlen=reqdig+1;
+ }
+ if (newlen>usellen)
+ usellen=newlen; // need to pad LHS
+ }
+ else{ // need to pad rhs and/or truncate lhs
+ newlen=(userlen+rhs.exp)-lhs.exp;
+ if (newlen>=((usellen+reqdig)+1))
+ if (reqdig>0)
+ {
+ // RHS is sufficient
+ res.mant=user;
+ res.exp=rhs.exp;
+ res.ind=rhs.ind;
+ if (userlen<reqdig)
+ { // need 0 padding
+ res.mant=extend(rhs.mant,reqdig);
+ res.exp=res.exp-((reqdig-userlen));
+ }
+ return res.finish(set,false);
+ }
+ // LHS may affect result
+ res.exp=lhs.exp; // expected final exponent
+ if (newlen>(reqdig+1))
+ if (reqdig>0)
+ {
+ // RHS will be max; LHS truncated
+ tlen=(newlen-reqdig)-1; // truncation length
+ usellen=usellen-tlen;
+ res.exp=res.exp+tlen;
+ newlen=reqdig+1;
+ }
+ if (newlen>userlen)
+ userlen=newlen; // need to pad RHS
+ }
+ }while(false);}/*padder*/
+
+ /* OK, we have aligned mantissas. Now add or subtract. */
+ // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
+ // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
+ // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
+ if (lhs.ind==iszero)
+ res.ind=ispos;
+ else
+ res.ind=lhs.ind; // likely sign, all paths
+ if (((lhs.ind==isneg)?1:0)==((rhs.ind==isneg)?1:0)) // same sign, 0 non-negative
+ mult=1;
+ else
+ {do{ // different signs, so subtraction is needed
+ mult=-1; // will cause subtract
+ /* Before we can subtract we must determine which is the larger,
+ as our add/subtract routine only handles non-negative results
+ so we may need to swap the operands. */
+ {do{/*select*/
+ if (rhs.ind==iszero){
+ // original A bigger
+ }else if ((usellen<userlen)|(lhs.ind==iszero))
+ { // original B bigger
+ t=usel;
+ usel=user;
+ user=t; // swap
+ tlen=usellen;
+ usellen=userlen;
+ userlen=tlen; // ..
+ res.ind=(byte)-res.ind; // and set sign
+ }
+ else if (usellen>userlen){
+ // original A bigger
+ }else{
+ {/* logical lengths the same */ // need compare
+ /* may still need to swap: compare the strings */
+ ia=0;
+ ib=0;
+ ea=usel.length-1;
+ eb=user.length-1;
+ {compare:for(;;){
+ if (ia<=ea)
+ ca=usel[ia];
+ else
+ {
+ if (ib>eb)
+ {/* identical */
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ return ZERO;
+ // [if PLAIN we must do the subtract, in case of 0.000 results]
+ break compare;
+ }
+ ca=(byte)0;
+ }
+ if (ib<=eb)
+ cb=user[ib];
+ else
+ cb=(byte)0;
+ if (ca!=cb)
+ {
+ if (ca<cb)
+ {/* swap needed */
+ t=usel;
+ usel=user;
+ user=t; // swap
+ tlen=usellen;
+ usellen=userlen;
+ userlen=tlen; // ..
+ res.ind=(byte)-res.ind;
+ }
+ break compare;
+ }
+ /* mantissas the same, so far */
+ ia++;
+ ib++;
+ }
+ }/*compare*/
+ } // lengths the same
+ }
+ }while(false);}/*swaptest*/
+ }while(false);}/*signdiff*/
+
+ /* here, A is > B if subtracting */
+ // add [A+B*1] or subtract [A+(B*-1)]
+ res.mant=byteaddsub(usel,usellen,user,userlen,mult,false);
+ // [reuse possible only after chop; accounting makes not worthwhile]
+
+ // Finish() rounds before stripping leading 0's, then sets form, etc.
+ return res.finish(set,false);
+ }
+
+ /**
+ * Compares this <code>BigDecimal</code> to another, using unlimited
+ * precision.
+ * <p>
+ * The same as {@link #compareTo(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @return An <code>int</code> whose value is -1, 0, or 1 as
+ * <code>this</code> is numerically less than, equal to,
+ * or greater than <code>rhs</code>.
+ * @see #compareTo(Object)
+ * @stable ICU 2.0
+ */
+
+ public int compareTo(com.ibm.icu.math.BigDecimal rhs){
+ return this.compareTo(rhs,plainMC);
+ }
+
+ /**
+ * Compares this <code>BigDecimal</code> to another.
+ * <p>
+ * Implements numeric comparison,
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns a result of type <code>int</code>.
+ * <p>
+ * The result will be:
+ * <table cellpadding=2><tr>
+ * <td align=right><b>-1</b></td>
+ * <td>if the current object is less than the first parameter</td>
+ * </tr><tr>
+ * <td align=right><b>0</b></td>
+ * <td>if the current object is equal to the first parameter</td>
+ * </tr><tr>
+ * <td align=right><b>1</b></td>
+ * <td>if the current object is greater than the first parameter.</td>
+ * </tr></table>
+ * <p>
+ * A {@link #compareTo(Object)} method is also provided.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return An <code>int</code> whose value is -1, 0, or 1 as
+ * <code>this</code> is numerically less than, equal to,
+ * or greater than <code>rhs</code>.
+ * @see #compareTo(Object)
+ * @stable ICU 2.0
+ */
+
+ public int compareTo(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ int thislength=0;
+ int i=0;
+ com.ibm.icu.math.BigDecimal newrhs;
+ // rhs=null will raise NullPointerException, as per Comparable interface
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ // [add will recheck in slowpath cases .. but would report -rhs]
+ if ((this.ind==rhs.ind)&(this.exp==rhs.exp))
+ {
+ /* sign & exponent the same [very common] */
+ thislength=this.mant.length;
+ if (thislength<rhs.mant.length)
+ return (byte)-this.ind;
+ if (thislength>rhs.mant.length)
+ return this.ind;
+ /* lengths are the same; we can do a straight mantissa compare
+ unless maybe rounding [rounding is very unusual] */
+ if ((thislength<=set.digits)|(set.digits==0))
+ {
+ {int $6=thislength;i=0;for(;$6>0;$6--,i++){
+ if (this.mant[i]<rhs.mant[i])
+ return (byte)-this.ind;
+ if (this.mant[i]>rhs.mant[i])
+ return this.ind;
+ }
+ }/*i*/
+ return 0; // identical
+ }
+ /* drop through for full comparison */
+ }
+ else
+ {
+ /* More fastpaths possible */
+ if (this.ind<rhs.ind)
+ return -1;
+ if (this.ind>rhs.ind)
+ return 1;
+ }
+ /* carry out a subtract to make the comparison */
+ newrhs=clone(rhs); // safe copy
+ newrhs.ind=(byte)-newrhs.ind; // prepare to subtract
+ return this.add(newrhs,set).ind; // add, and return sign of result
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #divide(BigDecimal, int)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the rounding mode is {@link MathContext#ROUND_HALF_UP}.
+ *
+ * The length of the decimal part (the scale) of the result will be
+ * the same as the scale of the current object, if the latter were
+ * formatted without exponential notation.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the division.
+ * @return A plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs){
+ return this.dodivide('D',rhs,plainMC,-1);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic and a
+ * rounding mode.
+ * <p>
+ * The same as {@link #divide(BigDecimal, int, int)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the second parameter is <code>this.scale()</code>, and
+ * the third is <code>round</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will
+ * therefore be the same as the scale of the current object, if the
+ * latter were formatted without exponential notation.
+ * <p>
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the division.
+ * @param round The <code>int</code> rounding mode to be used for
+ * the division (see the {@link MathContext} class).
+ * @return A plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic
+ * and the specified rounding mode.
+ * @throws IllegalArgumentException if <code>round</code> is not a
+ * valid rounding mode.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @throws ArithmeticException if <code>round</code> is {@link
+ * MathContext#ROUND_UNNECESSARY} and
+ * <code>this.scale()</code> is insufficient to
+ * represent the result exactly.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,int round){
+ com.ibm.icu.math.MathContext set;
+ set=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN,false,round); // [checks round, too]
+ return this.dodivide('D',rhs,set,-1); // take scale from LHS
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic and a
+ * given scale and rounding mode.
+ * <p>
+ * The same as {@link #divide(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>,
+ * except that the length of the decimal part (the scale) to be used
+ * for the result is explicit rather than being taken from
+ * <code>this</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * the same as the scale of the current object, if the latter were
+ * formatted without exponential notation.
+ * <p>
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the division.
+ * @param scale The <code>int</code> scale to be used for the result.
+ * @param round The <code>int</code> rounding mode to be used for
+ * the division (see the {@link MathContext} class).
+ * @return A plain <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>, using fixed point arithmetic
+ * and the specified rounding mode.
+ * @throws IllegalArgumentException if <code>round</code> is not a
+ * valid rounding mode.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @throws ArithmeticException if <code>scale</code> is negative.
+ * @throws ArithmeticException if <code>round</code> is {@link
+ * MathContext#ROUND_UNNECESSARY} and <code>scale</code>
+ * is insufficient to represent the result exactly.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,int scale,int round){
+ com.ibm.icu.math.MathContext set;
+ if (scale<0)
+ throw new java.lang.ArithmeticException("Negative scale:"+" "+scale);
+ set=new com.ibm.icu.math.MathContext(0,com.ibm.icu.math.MathContext.PLAIN,false,round); // [checks round]
+ return this.dodivide('D',rhs,set,scale);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
+ * <p>
+ * Implements the division (<b><code>/</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the division.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this/rhs</code>.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ return this.dodivide('D',rhs,set,-1);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is the integer
+ * part of <code>this/rhs</code>.
+ * <p>
+ * The same as {@link #divideInteger(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the integer division.
+ * @return A <code>BigDecimal</code> whose value is the integer
+ * part of <code>this/rhs</code>.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs){
+ // scale 0 to drop .000 when plain
+ return this.dodivide('I',rhs,plainMC,0);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is the integer
+ * part of <code>this/rhs</code>.
+ * <p>
+ * Implements the integer division operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the integer division.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is the integer
+ * part of <code>this/rhs</code>.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @throws ArithmeticException if the result will not fit in the
+ * number of digits specified for the context.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ // scale 0 to drop .000 when plain
+ return this.dodivide('I',rhs,set,0);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * the maximum of <code>this</code> and <code>rhs</code>.
+ * <p>
+ * The same as {@link #max(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @return A <code>BigDecimal</code> whose value is
+ * the maximum of <code>this</code> and <code>rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs){
+ return this.max(rhs,plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is
+ * the maximum of <code>this</code> and <code>rhs</code>.
+ * <p>
+ * Returns the larger of the current object and the first parameter.
+ * <p>
+ * If calling the {@link #compareTo(BigDecimal, MathContext)} method
+ * with the same parameters would return <code>1</code> or
+ * <code>0</code>, then the result of calling the
+ * {@link #plus(MathContext)} method on the current object (using the
+ * same <code>MathContext</code> parameter) is returned.
+ * Otherwise, the result of calling the {@link #plus(MathContext)}
+ * method on the first parameter object (using the same
+ * <code>MathContext</code> parameter) is returned.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * the maximum of <code>this</code> and <code>rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ if ((this.compareTo(rhs,set))>=0)
+ return this.plus(set);
+ else
+ return rhs.plus(set);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * the minimum of <code>this</code> and <code>rhs</code>.
+ * <p>
+ * The same as {@link #min(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @return A <code>BigDecimal</code> whose value is
+ * the minimum of <code>this</code> and <code>rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs){
+ return this.min(rhs,plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is
+ * the minimum of <code>this</code> and <code>rhs</code>.
+ * <p>
+ * Returns the smaller of the current object and the first parameter.
+ * <p>
+ * If calling the {@link #compareTo(BigDecimal, MathContext)} method
+ * with the same parameters would return <code>-1</code> or
+ * <code>0</code>, then the result of calling the
+ * {@link #plus(MathContext)} method on the current object (using the
+ * same <code>MathContext</code> parameter) is returned.
+ * Otherwise, the result of calling the {@link #plus(MathContext)}
+ * method on the first parameter object (using the same
+ * <code>MathContext</code> parameter) is returned.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the comparison.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * the minimum of <code>this</code> and <code>rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ if ((this.compareTo(rhs,set))<=0)
+ return this.plus(set);
+ else
+ return rhs.plus(set);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this*rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #add(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * the sum of the scales of the operands, if they were formatted
+ * without exponential notation.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the multiplication.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this*rhs</code>, using fixed point arithmetic.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs){
+ return this.multiply(rhs,plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
+ * <p>
+ * Implements the multiplication (<b><code>*</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the multiplication.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this*rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ com.ibm.icu.math.BigDecimal lhs;
+ int padding;
+ int reqdig;
+ byte multer[]=null;
+ byte multand[]=null;
+ int multandlen;
+ int acclen=0;
+ com.ibm.icu.math.BigDecimal res;
+ byte acc[];
+ int n=0;
+ byte mult=0;
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ lhs=this; // name for clarity and proxy
+
+ /* Prepare numbers (truncate, unless unlimited precision) */
+ padding=0; // trailing 0's to add
+ reqdig=set.digits; // local copy
+ if (reqdig>0)
+ {
+ if (lhs.mant.length>reqdig)
+ lhs=clone(lhs).round(set);
+ if (rhs.mant.length>reqdig)
+ rhs=clone(rhs).round(set);
+ // [we could reuse the new LHS for result in this case]
+ }
+ else
+ {/* unlimited */
+ // fixed point arithmetic will want every trailing 0; we add these
+ // after the calculation rather than before, for speed.
+ if (lhs.exp>0)
+ padding=padding+lhs.exp;
+ if (rhs.exp>0)
+ padding=padding+rhs.exp;
+ }
+
+ // For best speed, as in DMSRCN, we use the shorter number as the
+ // multiplier and the longer as the multiplicand.
+ // 1999.12.22: We used to special case when the result would fit in
+ // a long, but with Java 1.3 this gave no advantage.
+ if (lhs.mant.length<rhs.mant.length)
+ {
+ multer=lhs.mant;
+ multand=rhs.mant;
+ }
+ else
+ {
+ multer=rhs.mant;
+ multand=lhs.mant;
+ }
+
+ /* Calculate how long result byte array will be */
+ multandlen=(multer.length+multand.length)-1; // effective length
+ // optimize for 75% of the cases where a carry is expected...
+ if ((multer[0]*multand[0])>9)
+ acclen=multandlen+1;
+ else
+ acclen=multandlen;
+
+ /* Now the main long multiplication loop */
+ res=new com.ibm.icu.math.BigDecimal(); // where we'll build result
+ acc=new byte[acclen]; // accumulator, all zeros
+ // 1998.07.01: calculate from left to right so that accumulator goes
+ // to likely final length on first addition; this avoids a one-digit
+ // extension (and object allocation) each time around the loop.
+ // Initial number therefore has virtual zeros added to right.
+ {int $7=multer.length;n=0;for(;$7>0;$7--,n++){
+ mult=multer[n];
+ if (mult!=0)
+ { // [optimization]
+ // accumulate [accumulator is reusable array]
+ acc=byteaddsub(acc,acc.length,multand,multandlen,mult,true);
+ }
+ // divide multiplicand by 10 for next digit to right
+ multandlen--; // 'virtual length'
+ }
+ }/*n*/
+
+ res.ind=(byte)(lhs.ind*rhs.ind); // final sign
+ res.exp=(lhs.exp+rhs.exp)-padding; // final exponent
+ // [overflow is checked by finish]
+
+ /* add trailing zeros to the result, if necessary */
+ if (padding==0)
+ res.mant=acc;
+ else
+ res.mant=extend(acc,acc.length+padding); // add trailing 0s
+ return res.finish(set,false);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>-this</code>.
+ * <p>
+ * The same as {@link #negate(MathContext)}, where the context is
+ * <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * be <code>this.scale()</code>
+ *
+ *
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>-this</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal negate(){
+ return this.negate(plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
+ * <p>
+ * Implements the negation (Prefix <b><code>-</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>-this</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set){
+ com.ibm.icu.math.BigDecimal res;
+ // Originally called minus(), changed to matched Java precedents
+ // This simply clones, flips the sign, and possibly rounds
+ if (set.lostDigits)
+ checkdigits((com.ibm.icu.math.BigDecimal)null,set.digits);
+ res=clone(this); // safe copy
+ res.ind=(byte)-res.ind;
+ return res.finish(set,false);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>+this</code>.
+ * Note that <code>this</code> is not necessarily a
+ * plain <code>BigDecimal</code>, but the result will always be.
+ * <p>
+ * The same as {@link #plus(MathContext)}, where the context is
+ * <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * be <code>this.scale()</code>
+ *
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>+this</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal plus(){
+ return this.plus(plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is
+ * <code>+this</code>.
+ * <p>
+ * Implements the plus (Prefix <b><code>+</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ * <p>
+ * This method is useful for rounding or otherwise applying a context
+ * to a decimal value.
+ *
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>+this</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set){
+ // This clones and forces the result to the new settings
+ // May return same object
+ if (set.lostDigits)
+ checkdigits((com.ibm.icu.math.BigDecimal)null,set.digits);
+ // Optimization: returns same object for some common cases
+ if (set.form==com.ibm.icu.math.MathContext.PLAIN)
+ if (this.form==com.ibm.icu.math.MathContext.PLAIN)
+ {
+ if (this.mant.length<=set.digits)
+ return this;
+ if (set.digits==0)
+ return this;
+ }
+ return clone(this).finish(set,false);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this**rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #pow(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The parameter is the power to which the <code>this</code> will be
+ * raised; it must be in the range 0 through 999999999, and must
+ * have a decimal part of zero. Note that these restrictions may be
+ * removed in the future, so they should not be used as a test for a
+ * whole number.
+ * <p>
+ * In addition, the power must not be negative, as no
+ * <code>MathContext</code> is used and so the result would then
+ * always be 0.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the operation (the power).
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this**rhs</code>, using fixed point arithmetic.
+ * @throws ArithmeticException if <code>rhs</code> is out of range or
+ * is not a whole number.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs){
+ return this.pow(rhs,plainMC);
+ }
+ // The name for this method is inherited from the precedent set by the
+ // BigInteger and Math classes.
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
+ * <p>
+ * Implements the power (<b><code>**</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ * <p>
+ * The first parameter is the power to which the <code>this</code>
+ * will be raised; it must be in the range -999999999 through
+ * 999999999, and must have a decimal part of zero. Note that these
+ * restrictions may be removed in the future, so they should not be
+ * used as a test for a whole number.
+ * <p>
+ * If the <code>digits</code> setting of the <code>MathContext</code>
+ * parameter is 0, the power must be zero or positive.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the operation (the power).
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this**rhs</code>.
+ * @throws ArithmeticException if <code>rhs</code> is out of range or
+ * is not a whole number.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ int n;
+ com.ibm.icu.math.BigDecimal lhs;
+ int reqdig;
+ int workdigits=0;
+ int L=0;
+ com.ibm.icu.math.MathContext workset;
+ com.ibm.icu.math.BigDecimal res;
+ boolean seenbit;
+ int i=0;
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ n=rhs.intcheck(MinArg,MaxArg); // check RHS by the rules
+ lhs=this; // clarified name
+
+ reqdig=set.digits; // local copy (heavily used)
+ if (reqdig==0)
+ {
+ if (rhs.ind==isneg)
+ throw new java.lang.ArithmeticException("Negative power:"+" "+rhs.toString());
+ workdigits=0;
+ }
+ else
+ {/* non-0 digits */
+ if ((rhs.mant.length+rhs.exp)>reqdig)
+ throw new java.lang.ArithmeticException("Too many digits:"+" "+rhs.toString());
+
+ /* Round the lhs to DIGITS if need be */
+ if (lhs.mant.length>reqdig)
+ lhs=clone(lhs).round(set);
+
+ /* L for precision calculation [see ANSI X3.274-1996] */
+ L=rhs.mant.length+rhs.exp; // length without decimal zeros/exp
+ workdigits=(reqdig+L)+1; // calculate the working DIGITS
+ }
+
+ /* Create a copy of set for working settings */
+ // Note: no need to check for lostDigits again.
+ // 1999.07.17 Note: this construction must follow RHS check
+ workset=new com.ibm.icu.math.MathContext(workdigits,set.form,false,set.roundingMode);
+
+ res=ONE; // accumulator
+ if (n==0)
+ return res; // x**0 == 1
+ if (n<0)
+ n=(int)-n; // [rhs.ind records the sign]
+ seenbit=false; // set once we've seen a 1-bit
+ {i=1;i:for(;;i++){ // for each bit [top bit ignored]
+ n=n+n; // shift left 1 bit
+ if (n<0)
+ { // top bit is set
+ seenbit=true; // OK, we're off
+ res=res.multiply(lhs,workset); // acc=acc*x
+ }
+ if (i==31)
+ break i; // that was the last bit
+ if ((!seenbit))
+ continue i; // we don't have to square 1
+ res=res.multiply(res,workset); // acc=acc*acc [square]
+ }
+ }/*i*/ // 32 bits
+ if (rhs.ind<0) // was a **-n [hence digits>0]
+ res=ONE.divide(res,workset); // .. so acc=1/acc
+ return res.finish(set,true); // round and strip [original digits]
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * the remainder of <code>this/rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #remainder(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * This is not the modulo operator -- the result may be negative.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the remainder operation.
+ * @return A <code>BigDecimal</code> whose value is the remainder
+ * of <code>this/rhs</code>, using fixed point arithmetic.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs){
+ return this.dodivide('R',rhs,plainMC,-1);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is the remainder of
+ * <code>this/rhs</code>.
+ * <p>
+ * Implements the remainder operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ * <p>
+ * This is not the modulo operator -- the result may be negative.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the remainder operation.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is the remainder
+ * of <code>this+rhs</code>.
+ * @throws ArithmeticException if <code>rhs</code> is zero.
+ * @throws ArithmeticException if the integer part of the result will
+ * not fit in the number of digits specified for the
+ * context.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ return this.dodivide('R',rhs,set,-1);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose value is
+ * <code>this-rhs</code>, using fixed point arithmetic.
+ * <p>
+ * The same as {@link #subtract(BigDecimal, MathContext)},
+ * where the <code>BigDecimal</code> is <code>rhs</code>,
+ * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
+ * <p>
+ * The length of the decimal part (the scale) of the result will be
+ * the maximum of the scales of the two operands.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the subtraction.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this-rhs</code>, using fixed point arithmetic.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs){
+ return this.subtract(rhs,plainMC);
+ }
+
+ /**
+ * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
+ * <p>
+ * Implements the subtraction (<b><code>-</code></b>) operator
+ * (as defined in the decimal documentation, see {@link BigDecimal
+ * class header}),
+ * and returns the result as a <code>BigDecimal</code> object.
+ *
+ * @param rhs The <code>BigDecimal</code> for the right hand side of
+ * the subtraction.
+ * @param set The <code>MathContext</code> arithmetic settings.
+ * @return A <code>BigDecimal</code> whose value is
+ * <code>this-rhs</code>.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set){
+ com.ibm.icu.math.BigDecimal newrhs;
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ // [add will recheck .. but would report -rhs]
+ /* carry out the subtraction */
+ // we could fastpath -0, but it is too rare.
+ newrhs=clone(rhs); // safe copy
+ newrhs.ind=(byte)-newrhs.ind; // prepare to subtract
+ return this.add(newrhs,set); // arithmetic
+ }
+
+ /* ---------------------------------------------------------------- */
+ /* Other methods */
+ /* ---------------------------------------------------------------- */
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>byte</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part or is
+ * out of the possible range for a <code>byte</code> (8-bit signed
+ * integer) result then an <code>ArithmeticException</code> is thrown.
+ *
+ * @return A <code>byte</code> equal in value to <code>this</code>.
+ * @throws ArithmeticException if <code>this</code> has a non-zero
+ * decimal part, or will not fit in a <code>byte</code>.
+ * @stable ICU 2.0
+ */
+
+ public byte byteValueExact(){
+ int num;
+ num=this.intValueExact(); // will check decimal part too
+ if ((num>127)|(num<(-128)))
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ return (byte)num;
+ }
+
+ /**
+ * Compares this <code>BigDecimal</code> with the value of the parameter.
+ * <p>
+ * If the parameter is <code>null</code>, or is not an instance of the
+ * <code>BigDecimal</code> type, an exception is thrown.
+ * Otherwise, the parameter is cast to type <code>BigDecimal</code>
+ * and the result of the {@link #compareTo(BigDecimal)} method,
+ * using the cast parameter, is returned.
+ * <p>
+ * The {@link #compareTo(BigDecimal, MathContext)} method should be
+ * used when a <code>MathContext</code> is needed for the comparison.
+ *
+ * @param rhsobj The <code>Object</code> for the right hand side of
+ * the comparison.
+ * @return An <code>int</code> whose value is -1, 0, or 1 as
+ * <code>this</code> is numerically less than, equal to,
+ * or greater than <code>rhs</code>.
+ * @throws ClassCastException if <code>rhs</code> cannot be cast to
+ * a <code>BigDecimal</code> object.
+ * @see #compareTo(BigDecimal)
+ * @stable ICU 2.0
+ */
+
+ public int compareTo(java.lang.Object rhsobj){
+ // the cast in the next line will raise ClassCastException if necessary
+ return compareTo((com.ibm.icu.math.BigDecimal)rhsobj,plainMC);
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>double</code>.
+ * If the <code>BigDecimal</code> is out of the possible range for a
+ * <code>double</code> (64-bit signed floating point) result then an
+ * <code>ArithmeticException</code> is thrown.
+ * <p>
+ * The double produced is identical to result of expressing the
+ * <code>BigDecimal</code> as a <code>String</code> and then
+ * converting it using the <code>Double(String)</code> constructor;
+ * this can result in values of <code>Double.NEGATIVE_INFINITY</code>
+ * or <code>Double.POSITIVE_INFINITY</code>.
+ *
+ * @return A <code>double</code> corresponding to <code>this</code>.
+ * @stable ICU 2.0
+ */
+
+ public double doubleValue(){
+ // We go via a String [as does BigDecimal in JDK 1.2]
+ // Next line could possibly raise NumberFormatException
+ return java.lang.Double.valueOf(this.toString()).doubleValue();
+ }
+
+ /**
+ * Compares this <code>BigDecimal</code> with <code>rhs</code> for
+ * equality.
+ * <p>
+ * If the parameter is <code>null</code>, or is not an instance of the
+ * BigDecimal type, or is not exactly equal to the current
+ * <code>BigDecimal</code> object, then <i>false</i> is returned.
+ * Otherwise, <i>true</i> is returned.
+ * <p>
+ * "Exactly equal", here, means that the <code>String</code>
+ * representations of the <code>BigDecimal</code> numbers are
+ * identical (they have the same characters in the same sequence).
+ * <p>
+ * The {@link #compareTo(BigDecimal, MathContext)} method should be
+ * used for more general comparisons.
+ * @param obj The <code>Object</code> for the right hand side of
+ * the comparison.
+ * @return A <code>boolean</code> whose value <i>true</i> if and
+ * only if the operands have identical string representations.
+ * @throws ClassCastException if <code>rhs</code> cannot be cast to
+ * a <code>BigDecimal</code> object.
+ * @stable ICU 2.0
+ * @see #compareTo(Object)
+ * @see #compareTo(BigDecimal)
+ * @see #compareTo(BigDecimal, MathContext)
+ */
+
+ public boolean equals(java.lang.Object obj){
+ com.ibm.icu.math.BigDecimal rhs;
+ int i=0;
+ char lca[]=null;
+ char rca[]=null;
+ // We are equal iff toString of both are exactly the same
+ if (obj==null)
+ return false; // not equal
+ if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
+ return false; // not a decimal
+ rhs=(com.ibm.icu.math.BigDecimal)obj; // cast; we know it will work
+ if (this.ind!=rhs.ind)
+ return false; // different signs never match
+ if (((this.mant.length==rhs.mant.length)&(this.exp==rhs.exp))&(this.form==rhs.form))
+
+ { // mantissas say all
+ // here with equal-length byte arrays to compare
+ {int $8=this.mant.length;i=0;for(;$8>0;$8--,i++){
+ if (this.mant[i]!=rhs.mant[i])
+ return false;
+ }
+ }/*i*/
+ }
+ else
+ { // need proper layout
+ lca=this.layout(); // layout to character array
+ rca=rhs.layout();
+ if (lca.length!=rca.length)
+ return false; // mismatch
+ // here with equal-length character arrays to compare
+ {int $9=lca.length;i=0;for(;$9>0;$9--,i++){
+ if (lca[i]!=rca[i])
+ return false;
+ }
+ }/*i*/
+ }
+ return true; // arrays have identical content
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>float</code>.
+ * If the <code>BigDecimal</code> is out of the possible range for a
+ * <code>float</code> (32-bit signed floating point) result then an
+ * <code>ArithmeticException</code> is thrown.
+ * <p>
+ * The float produced is identical to result of expressing the
+ * <code>BigDecimal</code> as a <code>String</code> and then
+ * converting it using the <code>Float(String)</code> constructor;
+ * this can result in values of <code>Float.NEGATIVE_INFINITY</code>
+ * or <code>Float.POSITIVE_INFINITY</code>.
+ *
+ * @return A <code>float</code> corresponding to <code>this</code>.
+ * @stable ICU 2.0
+ */
+
+ public float floatValue(){
+ return java.lang.Float.valueOf(this.toString()).floatValue();
+ }
+
+ /**
+ * Returns the <code>String</code> representation of this
+ * <code>BigDecimal</code>, modified by layout parameters.
+ * <p>
+ * <i>This method is provided as a primitive for use by more
+ * sophisticated classes, such as <code>DecimalFormat</code>, that
+ * can apply locale-sensitive editing of the result. The level of
+ * formatting that it provides is a necessary part of the BigDecimal
+ * class as it is sensitive to and must follow the calculation and
+ * rounding rules for BigDecimal arithmetic.
+ * However, if the function is provided elsewhere, it may be removed
+ * from this class. </i>
+ * <p>
+ * The parameters, for both forms of the <code>format</code> method
+ * are all of type <code>int</code>.
+ * A value of -1 for any parameter indicates that the default action
+ * or value for that parameter should be used.
+ * <p>
+ * The parameters, <code>before</code> and <code>after</code>,
+ * specify the number of characters to be used for the integer part
+ * and decimal part of the result respectively. Exponential notation
+ * is not used. If either parameter is -1 (which indicates the default
+ * action), the number of characters used will be exactly as many as
+ * are needed for that part.
+ * <p>
+ * <code>before</code> must be a positive number; if it is larger than
+ * is needed to contain the integer part, that part is padded on the
+ * left with blanks to the requested length. If <code>before</code> is
+ * not large enough to contain the integer part of the number
+ * (including the sign, for negative numbers) an exception is thrown.
+ * <p>
+ * <code>after</code> must be a non-negative number; if it is not the
+ * same size as the decimal part of the number, the number will be
+ * rounded (or extended with zeros) to fit. Specifying 0 for
+ * <code>after</code> will cause the number to be rounded to an
+ * integer (that is, it will have no decimal part or decimal point).
+ * The rounding method will be the default,
+ * <code>MathContext.ROUND_HALF_UP</code>.
+ * <p>
+ * Other rounding methods, and the use of exponential notation, can
+ * be selected by using {@link #format(int,int,int,int,int,int)}.
+ * Using the two-parameter form of the method has exactly the same
+ * effect as using the six-parameter form with the final four
+ * parameters all being -1.
+ *
+ * @param before The <code>int</code> specifying the number of places
+ * before the decimal point. Use -1 for 'as many as
+ * are needed'.
+ * @param after The <code>int</code> specifying the number of places
+ * after the decimal point. Use -1 for 'as many as are
+ * needed'.
+ * @return A <code>String</code> representing this
+ * <code>BigDecimal</code>, laid out according to the
+ * specified parameters
+ * @throws ArithmeticException if the number cannot be laid out as
+ * requested.
+ * @throws IllegalArgumentException if a parameter is out of range.
+ * @stable ICU 2.0
+ * @see #toString
+ * @see #toCharArray
+ */
+
+ public java.lang.String format(int before,int after){
+ return format(before,after,-1,-1,com.ibm.icu.math.MathContext.SCIENTIFIC,ROUND_HALF_UP);
+ }
+
+ /**
+ * Returns the <code>String</code> representation of this
+ * <code>BigDecimal</code>, modified by layout parameters and allowing
+ * exponential notation.
+ * <p>
+ * <i>This method is provided as a primitive for use by more
+ * sophisticated classes, such as <code>DecimalFormat</code>, that
+ * can apply locale-sensitive editing of the result. The level of
+ * formatting that it provides is a necessary part of the BigDecimal
+ * class as it is sensitive to and must follow the calculation and
+ * rounding rules for BigDecimal arithmetic.
+ * However, if the function is provided elsewhere, it may be removed
+ * from this class. </i>
+ * <p>
+ * The parameters are all of type <code>int</code>.
+ * A value of -1 for any parameter indicates that the default action
+ * or value for that parameter should be used.
+ * <p>
+ * The first two parameters (<code>before</code> and
+ * <code>after</code>) specify the number of characters to be used for
+ * the integer part and decimal part of the result respectively, as
+ * defined for {@link #format(int,int)}.
+ * If either of these is -1 (which indicates the default action), the
+ * number of characters used will be exactly as many as are needed for
+ * that part.
+ * <p>
+ * The remaining parameters control the use of exponential notation
+ * and rounding. Three (<code>explaces</code>, <code>exdigits</code>,
+ * and <code>exform</code>) control the exponent part of the result.
+ * As before, the default action for any of these parameters may be
+ * selected by using the value -1.
+ * <p>
+ * <code>explaces</code> must be a positive number; it sets the number
+ * of places (digits after the sign of the exponent) to be used for
+ * any exponent part, the default (when <code>explaces</code> is -1)
+ * being to use as many as are needed.
+ * If <code>explaces</code> is not -1, space is always reserved for
+ * an exponent; if one is not needed (for example, if the exponent
+ * will be 0) then <code>explaces</code>+2 blanks are appended to the
+ * result.
+ * <!-- (This preserves vertical alignment of similarly formatted
+ * numbers in a monospace font.) -->
+ * If <code>explaces</code> is not -1 and is not large enough to
+ * contain the exponent, an exception is thrown.
+ * <p>
+ * <code>exdigits</code> sets the trigger point for use of exponential
+ * notation. If, before any rounding, the number of places needed
+ * before the decimal point exceeds <code>exdigits</code>, or if the
+ * absolute value of the result is less than <code>0.000001</code>,
+ * then exponential form will be used, provided that
+ * <code>exdigits</code> was specified.
+ * When <code>exdigits</code> is -1, exponential notation will never
+ * be used. If 0 is specified for <code>exdigits</code>, exponential
+ * notation is always used unless the exponent would be 0.
+ * <p>
+ * <code>exform</code> sets the form for exponential notation (if
+ * needed).
+ * It may be either {@link MathContext#SCIENTIFIC} or
+ * {@link MathContext#ENGINEERING}.
+ * If the latter, engineering, form is requested, up to three digits
+ * (plus sign, if negative) may be needed for the integer part of the
+ * result (<code>before</code>). Otherwise, only one digit (plus
+ * sign, if negative) is needed.
+ * <p>
+ * Finally, the sixth argument, <code>exround</code>, selects the
+ * rounding algorithm to be used, and must be one of the values
+ * indicated by a public constant in the {@link MathContext} class
+ * whose name starts with <code>ROUND_</code>.
+ * The default (<code>ROUND_HALF_UP</code>) may also be selected by
+ * using the value -1, as before.
+ * <p>
+ * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be
+ * used to detect whether non-zero digits are discarded -- if
+ * <code>exround</code> has this value than if non-zero digits would
+ * be discarded (rounded) during formatting then an
+ * <code>ArithmeticException</code> is thrown.
+ *
+ * @param before The <code>int</code> specifying the number of places
+ * before the decimal point.
+ * Use -1 for 'as many as are needed'.
+ * @param after The <code>int</code> specifying the number of places
+ * after the decimal point.
+ * Use -1 for 'as many as are needed'.
+ * @param explaces The <code>int</code> specifying the number of places
+ * to be used for any exponent.
+ * Use -1 for 'as many as are needed'.
+ * @param exdigits The <code>int</code> specifying the trigger
+ * (digits before the decimal point) which if
+ * exceeded causes exponential notation to be used.
+ * Use 0 to force exponential notation.
+ * Use -1 to force plain notation (no exponential
+ * notation).
+ * @param exformint The <code>int</code> specifying the form of
+ * exponential notation to be used
+ * ({@link MathContext#SCIENTIFIC} or
+ * {@link MathContext#ENGINEERING}).
+ * @param exround The <code>int</code> specifying the rounding mode
+ * to use.
+ * Use -1 for the default, {@link MathContext#ROUND_HALF_UP}.
+ * @return A <code>String</code> representing this
+ * <code>BigDecimal</code>, laid out according to the
+ * specified parameters
+ * @throws ArithmeticException if the number cannot be laid out as
+ * requested.
+ * @throws IllegalArgumentException if a parameter is out of range.
+ * @see #toString
+ * @see #toCharArray
+ * @stable ICU 2.0
+ */
+
+ public java.lang.String format(int before,int after,int explaces,int exdigits,int exformint,int exround){
+ com.ibm.icu.math.BigDecimal num;
+ int mag=0;
+ int thisafter=0;
+ int lead=0;
+ byte newmant[]=null;
+ int chop=0;
+ int need=0;
+ int oldexp=0;
+ char a[];
+ int p=0;
+ char newa[]=null;
+ int i=0;
+ int places=0;
+
+
+ /* Check arguments */
+ if ((before<(-1))|(before==0))
+ badarg("format",1,java.lang.String.valueOf(before));
+ if (after<(-1))
+ badarg("format",2,java.lang.String.valueOf(after));
+ if ((explaces<(-1))|(explaces==0))
+ badarg("format",3,java.lang.String.valueOf(explaces));
+ if (exdigits<(-1))
+ badarg("format",4,java.lang.String.valueOf(explaces));
+ {/*select*/
+ if (exformint==com.ibm.icu.math.MathContext.SCIENTIFIC){
+ }else if (exformint==com.ibm.icu.math.MathContext.ENGINEERING){
+ }else if (exformint==(-1))
+ exformint=com.ibm.icu.math.MathContext.SCIENTIFIC;
+ // note PLAIN isn't allowed
+ else{
+ badarg("format",5,java.lang.String.valueOf(exformint));
+ }
+ }
+ // checking the rounding mode is done by trying to construct a
+ // MathContext object with that mode; it will fail if bad
+ if (exround!=ROUND_HALF_UP)
+ {try{ // if non-default...
+ if (exround==(-1))
+ exround=ROUND_HALF_UP;
+ else
+ new com.ibm.icu.math.MathContext(9,com.ibm.icu.math.MathContext.SCIENTIFIC,false,exround);
+ }
+ catch (java.lang.IllegalArgumentException $10){
+ badarg("format",6,java.lang.String.valueOf(exround));
+ }}
+
+ num=clone(this); // make private copy
+
+ /* Here:
+ num is BigDecimal to format
+ before is places before point [>0]
+ after is places after point [>=0]
+ explaces is exponent places [>0]
+ exdigits is exponent digits [>=0]
+ exformint is exponent form [one of two]
+ exround is rounding mode [one of eight]
+ 'before' through 'exdigits' are -1 if not specified
+ */
+
+ /* determine form */
+ {do{/*select*/
+ if (exdigits==(-1))
+ num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;
+ else if (num.ind==iszero)
+ num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;
+ else{
+ // determine whether triggers
+ mag=num.exp+num.mant.length;
+ if (mag>exdigits)
+ num.form=(byte)exformint;
+ else
+ if (mag<(-5))
+ num.form=(byte)exformint;
+ else
+ num.form=(byte)com.ibm.icu.math.MathContext.PLAIN;
+ }
+ }while(false);}/*setform*/
+
+ /* If 'after' was specified then we may need to adjust the
+ mantissa. This is a little tricky, as we must conform to the
+ rules of exponential layout if necessary (e.g., we cannot end up
+ with 10.0 if scientific). */
+ if (after>=0)
+ {setafter:for(;;){
+ // calculate the current after-length
+ {/*select*/
+ if (num.form==com.ibm.icu.math.MathContext.PLAIN)
+ thisafter=(int)-num.exp; // has decimal part
+ else if (num.form==com.ibm.icu.math.MathContext.SCIENTIFIC)
+ thisafter=num.mant.length-1;
+ else{ // engineering
+ lead=(((num.exp+num.mant.length)-1))%3; // exponent to use
+ if (lead<0)
+ lead=3+lead; // negative exponent case
+ lead++; // number of leading digits
+ if (lead>=num.mant.length)
+ thisafter=0;
+ else
+ thisafter=num.mant.length-lead;
+ }
+ }
+ if (thisafter==after)
+ break setafter; // we're in luck
+ if (thisafter<after)
+ { // need added trailing zeros
+ // [thisafter can be negative]
+ newmant=extend(num.mant,(num.mant.length+after)-thisafter);
+ num.mant=newmant;
+ num.exp=num.exp-((after-thisafter)); // adjust exponent
+ if (num.exp<MinExp)
+ throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+num.exp);
+ break setafter;
+ }
+ // We have too many digits after the decimal point; this could
+ // cause a carry, which could change the mantissa...
+ // Watch out for implied leading zeros in PLAIN case
+ chop=thisafter-after; // digits to lop [is >0]
+ if (chop>num.mant.length)
+ { // all digits go, no chance of carry
+ // carry on with zero
+ num.mant=ZERO.mant;
+ num.ind=iszero;
+ num.exp=0;
+ continue setafter; // recheck: we may need trailing zeros
+ }
+ // we have a digit to inspect from existing mantissa
+ // round the number as required
+ need=num.mant.length-chop; // digits to end up with [may be 0]
+ oldexp=num.exp; // save old exponent
+ num.round(need,exround);
+ // if the exponent grew by more than the digits we chopped, then
+ // we must have had a carry, so will need to recheck the layout
+ if ((num.exp-oldexp)==chop)
+ break setafter; // number did not have carry
+ // mantissa got extended .. so go around and check again
+ }
+ }/*setafter*/
+
+ a=num.layout(); // lay out, with exponent if required, etc.
+
+ /* Here we have laid-out number in 'a' */
+ // now apply 'before' and 'explaces' as needed
+ if (before>0)
+ {
+ // look for '.' or 'E'
+ {int $11=a.length;p=0;p:for(;$11>0;$11--,p++){
+ if (a[p]=='.')
+ break p;
+ if (a[p]=='E')
+ break p;
+ }
+ }/*p*/
+ // p is now offset of '.', 'E', or character after end of array
+ // that is, the current length of before part
+ if (p>before)
+ badarg("format",1,java.lang.String.valueOf(before)); // won't fit
+ if (p<before)
+ { // need leading blanks
+ newa=new char[(a.length+before)-p];
+ {int $12=before-p;i=0;for(;$12>0;$12--,i++){
+ newa[i]=' ';
+ }
+ }/*i*/
+ java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,i,a.length);
+ a=newa;
+ }
+ // [if p=before then it's just the right length]
+ }
+
+ if (explaces>0)
+ {
+ // look for 'E' [cannot be at offset 0]
+ {int $13=a.length-1;p=a.length-1;p:for(;$13>0;$13--,p--){
+ if (a[p]=='E')
+ break p;
+ }
+ }/*p*/
+ // p is now offset of 'E', or 0
+ if (p==0)
+ { // no E part; add trailing blanks
+ newa=new char[(a.length+explaces)+2];
+ java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,0,a.length);
+ {int $14=explaces+2;i=a.length;for(;$14>0;$14--,i++){
+ newa[i]=' ';
+ }
+ }/*i*/
+ a=newa;
+ }
+ else
+ {/* found E */ // may need to insert zeros
+ places=(a.length-p)-2; // number so far
+ if (places>explaces)
+ badarg("format",3,java.lang.String.valueOf(explaces));
+ if (places<explaces)
+ { // need to insert zeros
+ newa=new char[(a.length+explaces)-places];
+ java.lang.System.arraycopy((java.lang.Object)a,0,(java.lang.Object)newa,0,p+2); // through E and sign
+ {int $15=explaces-places;i=p+2;for(;$15>0;$15--,i++){
+ newa[i]='0';
+ }
+ }/*i*/
+ java.lang.System.arraycopy((java.lang.Object)a,p+2,(java.lang.Object)newa,i,places); // remainder of exponent
+ a=newa;
+ }
+ // [if places=explaces then it's just the right length]
+ }
+ }
+ return new java.lang.String(a);
+ }
+
+ /**
+ * Returns the hashcode for this <code>BigDecimal</code>.
+ * This hashcode is suitable for use by the
+ * <code>java.util.Hashtable</code> class.
+ * <p>
+ * Note that two <code>BigDecimal</code> objects are only guaranteed
+ * to produce the same hashcode if they are exactly equal (that is,
+ * the <code>String</code> representations of the
+ * <code>BigDecimal</code> numbers are identical -- they have the same
+ * characters in the same sequence).
+ *
+ * @return An <code>int</code> that is the hashcode for <code>this</code>.
+ * @stable ICU 2.0
+ */
+
+ public int hashCode(){
+ // Maybe calculate ourselves, later. If so, note that there can be
+ // more than one internal representation for a given toString() result.
+ return this.toString().hashCode();
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to an <code>int</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part it is
+ * discarded. If the <code>BigDecimal</code> is out of the possible
+ * range for an <code>int</code> (32-bit signed integer) result then
+ * only the low-order 32 bits are used. (That is, the number may be
+ * <i>decapitated</i>.) To avoid unexpected errors when these
+ * conditions occur, use the {@link #intValueExact} method.
+ *
+ * @return An <code>int</code> converted from <code>this</code>,
+ * truncated and decapitated if necessary.
+ * @stable ICU 2.0
+ */
+
+ public int intValue(){
+ return toBigInteger().intValue();
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to an <code>int</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part or is
+ * out of the possible range for an <code>int</code> (32-bit signed
+ * integer) result then an <code>ArithmeticException</code> is thrown.
+ *
+ * @return An <code>int</code> equal in value to <code>this</code>.
+ * @throws ArithmeticException if <code>this</code> has a non-zero
+ * decimal part, or will not fit in an
+ * <code>int</code>.
+ * @stable ICU 2.0
+ */
+
+ public int intValueExact(){
+ int lodigit;
+ int useexp=0;
+ int result;
+ int i=0;
+ int topdig=0;
+ // This does not use longValueExact() as the latter can be much
+ // slower.
+ // intcheck (from pow) relies on this to check decimal part
+ if (ind==iszero)
+ return 0; // easy, and quite common
+ /* test and drop any trailing decimal part */
+ lodigit=mant.length-1;
+ if (exp<0)
+ {
+ lodigit=lodigit+exp; // reduces by -(-exp)
+ /* all decimal places must be 0 */
+ if ((!(allzero(mant,lodigit+1))))
+ throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());
+ if (lodigit<0)
+ return 0; // -1<this<1
+ useexp=0;
+ }
+ else
+ {/* >=0 */
+ if ((exp+lodigit)>9) // early exit
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ useexp=exp;
+ }
+ /* convert the mantissa to binary, inline for speed */
+ result=0;
+ {int $16=lodigit+useexp;i=0;for(;i<=$16;i++){
+ result=result*10;
+ if (i<=lodigit)
+ result=result+mant[i];
+ }
+ }/*i*/
+
+ /* Now, if the risky length, check for overflow */
+ if ((lodigit+useexp)==9)
+ {
+ // note we cannot just test for -ve result, as overflow can move a
+ // zero into the top bit [consider 5555555555]
+ topdig=result/1000000000; // get top digit, preserving sign
+ if (topdig!=mant[0])
+ { // digit must match and be positive
+ // except in the special case ...
+ if (result==java.lang.Integer.MIN_VALUE) // looks like the special
+ if (ind==isneg) // really was negative
+ if (mant[0]==2)
+ return result; // really had top digit 2
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ }
+ }
+
+ /* Looks good */
+ if (ind==ispos)
+ return result;
+ return (int)-result;
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>long</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part it is
+ * discarded. If the <code>BigDecimal</code> is out of the possible
+ * range for a <code>long</code> (64-bit signed integer) result then
+ * only the low-order 64 bits are used. (That is, the number may be
+ * <i>decapitated</i>.) To avoid unexpected errors when these
+ * conditions occur, use the {@link #longValueExact} method.
+ *
+ * @return A <code>long</code> converted from <code>this</code>,
+ * truncated and decapitated if necessary.
+ * @stable ICU 2.0
+ */
+
+ public long longValue(){
+ return toBigInteger().longValue();
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>long</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part or is
+ * out of the possible range for a <code>long</code> (64-bit signed
+ * integer) result then an <code>ArithmeticException</code> is thrown.
+ *
+ * @return A <code>long</code> equal in value to <code>this</code>.
+ * @throws ArithmeticException if <code>this</code> has a non-zero
+ * decimal part, or will not fit in a
+ * <code>long</code>.
+ * @stable ICU 2.0
+ */
+
+ public long longValueExact(){
+ int lodigit;
+ int cstart=0;
+ int useexp=0;
+ long result;
+ int i=0;
+ long topdig=0;
+ // Identical to intValueExact except for result=long, and exp>=20 test
+ if (ind==0)
+ return 0; // easy, and quite common
+ lodigit=mant.length-1; // last included digit
+ if (exp<0)
+ {
+ lodigit=lodigit+exp; // -(-exp)
+ /* all decimal places must be 0 */
+ if (lodigit<0)
+ cstart=0;
+ else
+ cstart=lodigit+1;
+ if ((!(allzero(mant,cstart))))
+ throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());
+ if (lodigit<0)
+ return 0; // -1<this<1
+ useexp=0;
+ }
+ else
+ {/* >=0 */
+ if ((exp+mant.length)>18) // early exit
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ useexp=exp;
+ }
+
+ /* convert the mantissa to binary, inline for speed */
+ // note that we could safely use the 'test for wrap to negative'
+ // algorithm here, but instead we parallel the intValueExact
+ // algorithm for ease of checking and maintenance.
+ result=(long)0;
+ {int $17=lodigit+useexp;i=0;for(;i<=$17;i++){
+ result=result*10;
+ if (i<=lodigit)
+ result=result+mant[i];
+ }
+ }/*i*/
+
+ /* Now, if the risky length, check for overflow */
+ if ((lodigit+useexp)==18)
+ {
+ topdig=result/1000000000000000000L; // get top digit, preserving sign
+ if (topdig!=mant[0])
+ { // digit must match and be positive
+ // except in the special case ...
+ if (result==java.lang.Long.MIN_VALUE) // looks like the special
+ if (ind==isneg) // really was negative
+ if (mant[0]==9)
+ return result; // really had top digit 9
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ }
+ }
+
+ /* Looks good */
+ if (ind==ispos)
+ return result;
+ return (long)-result;
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose decimal point has
+ * been moved to the left by a specified number of positions.
+ * The parameter, <code>n</code>, specifies the number of positions to
+ * move the decimal point.
+ * That is, if <code>n</code> is 0 or positive, the number returned is
+ * given by:
+ * <p><code>
+ * this.multiply(TEN.pow(new BigDecimal(-n)))
+ * </code>
+ * <p>
+ * <code>n</code> may be negative, in which case the method returns
+ * the same result as <code>movePointRight(-n)</code>.
+ *
+ * @param n The <code>int</code> specifying the number of places to
+ * move the decimal point leftwards.
+ * @return A <code>BigDecimal</code> derived from
+ * <code>this</code>, with the decimal point moved
+ * <code>n</code> places to the left.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal movePointLeft(int n){
+ com.ibm.icu.math.BigDecimal res;
+ // very little point in optimizing for shift of 0
+ res=clone(this);
+ res.exp=res.exp-n;
+ return res.finish(plainMC,false); // finish sets form and checks exponent
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> whose decimal point has
+ * been moved to the right by a specified number of positions.
+ * The parameter, <code>n</code>, specifies the number of positions to
+ * move the decimal point.
+ * That is, if <code>n</code> is 0 or positive, the number returned is
+ * given by:
+ * <p><code>
+ * this.multiply(TEN.pow(new BigDecimal(n)))
+ * </code>
+ * <p>
+ * <code>n</code> may be negative, in which case the method returns
+ * the same result as <code>movePointLeft(-n)</code>.
+ *
+ * @param n The <code>int</code> specifying the number of places to
+ * move the decimal point rightwards.
+ * @return A <code>BigDecimal</code> derived from
+ * <code>this</code>, with the decimal point moved
+ * <code>n</code> places to the right.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal movePointRight(int n){
+ com.ibm.icu.math.BigDecimal res;
+ res=clone(this);
+ res.exp=res.exp+n;
+ return res.finish(plainMC,false);
+ }
+
+ /**
+ * Returns the scale of this <code>BigDecimal</code>.
+ * Returns a non-negative <code>int</code> which is the scale of the
+ * number. The scale is the number of digits in the decimal part of
+ * the number if the number were formatted without exponential
+ * notation.
+ *
+ * @return An <code>int</code> whose value is the scale of this
+ * <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public int scale(){
+ if (exp>=0)
+ return 0; // scale can never be negative
+ return (int)-exp;
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> with a given scale.
+ * <p>
+ * If the given scale (which must be zero or positive) is the same as
+ * or greater than the length of the decimal part (the scale) of this
+ * <code>BigDecimal</code> then trailing zeros will be added to the
+ * decimal part as necessary.
+ * <p>
+ * If the given scale is less than the length of the decimal part (the
+ * scale) of this <code>BigDecimal</code> then trailing digits
+ * will be removed, and in this case an
+ * <code>ArithmeticException</code> is thrown if any discarded digits
+ * are non-zero.
+ * <p>
+ * The same as {@link #setScale(int, int)}, where the first parameter
+ * is the scale, and the second is
+ * <code>MathContext.ROUND_UNNECESSARY</code>.
+ *
+ * @param scale The <code>int</code> specifying the scale of the
+ * resulting <code>BigDecimal</code>.
+ * @return A plain <code>BigDecimal</code> with the given scale.
+ * @throws ArithmeticException if <code>scale</code> is negative.
+ * @throws ArithmeticException if reducing scale would discard
+ * non-zero digits.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal setScale(int scale){
+ return setScale(scale,ROUND_UNNECESSARY);
+ }
+
+ /**
+ * Returns a plain <code>BigDecimal</code> with a given scale.
+ * <p>
+ * If the given scale (which must be zero or positive) is the same as
+ * or greater than the length of the decimal part (the scale) of this
+ * <code>BigDecimal</code> then trailing zeros will be added to the
+ * decimal part as necessary.
+ * <p>
+ * If the given scale is less than the length of the decimal part (the
+ * scale) of this <code>BigDecimal</code> then trailing digits
+ * will be removed, and the rounding mode given by the second
+ * parameter is used to determine if the remaining digits are
+ * affected by a carry.
+ * In this case, an <code>IllegalArgumentException</code> is thrown if
+ * <code>round</code> is not a valid rounding mode.
+ * <p>
+ * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>,
+ * an <code>ArithmeticException</code> is thrown if any discarded
+ * digits are non-zero.
+ *
+ * @param scale The <code>int</code> specifying the scale of the
+ * resulting <code>BigDecimal</code>.
+ * @param round The <code>int</code> rounding mode to be used for
+ * the division (see the {@link MathContext} class).
+ * @return A plain <code>BigDecimal</code> with the given scale.
+ * @throws IllegalArgumentException if <code>round</code> is not a
+ * valid rounding mode.
+ * @throws ArithmeticException if <code>scale</code> is negative.
+ * @throws ArithmeticException if <code>round</code> is
+ * <code>MathContext.ROUND_UNNECESSARY</code>, and
+ * reducing scale would discard non-zero digits.
+ * @stable ICU 2.0
+ */
+
+ public com.ibm.icu.math.BigDecimal setScale(int scale,int round){
+ int ourscale;
+ com.ibm.icu.math.BigDecimal res;
+ int padding=0;
+ int newlen=0;
+ // at present this naughtily only checks the round value if it is
+ // needed (used), for speed
+ ourscale=this.scale();
+ if (ourscale==scale) // already correct scale
+ if (this.form==com.ibm.icu.math.MathContext.PLAIN) // .. and form
+ return this;
+ res=clone(this); // need copy
+ if (ourscale<=scale)
+ { // simply zero-padding/changing form
+ // if ourscale is 0 we may have lots of 0s to add
+ if (ourscale==0)
+ padding=res.exp+scale;
+ else
+ padding=scale-ourscale;
+ res.mant=extend(res.mant,res.mant.length+padding);
+ res.exp=(int)-scale; // as requested
+ }
+ else
+ {/* ourscale>scale: shortening, probably */
+ if (scale<0)
+ throw new java.lang.ArithmeticException("Negative scale:"+" "+scale);
+ // [round() will raise exception if invalid round]
+ newlen=res.mant.length-((ourscale-scale)); // [<=0 is OK]
+ res=res.round(newlen,round); // round to required length
+ // This could have shifted left if round (say) 0.9->1[.0]
+ // Repair if so by adding a zero and reducing exponent
+ if (res.exp!=((int)-scale))
+ {
+ res.mant=extend(res.mant,res.mant.length+1);
+ res.exp=res.exp-1;
+ }
+ }
+ res.form=(byte)com.ibm.icu.math.MathContext.PLAIN; // by definition
+ return res;
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a <code>short</code>.
+ * If the <code>BigDecimal</code> has a non-zero decimal part or is
+ * out of the possible range for a <code>short</code> (16-bit signed
+ * integer) result then an <code>ArithmeticException</code> is thrown.
+ *
+ * @return A <code>short</code> equal in value to <code>this</code>.
+ * @throws ArithmeticException if <code>this</code> has a non-zero
+ * decimal part, or will not fit in a
+ * <code>short</code>.
+ * @stable ICU 2.0
+ */
+
+ public short shortValueExact(){
+ int num;
+ num=this.intValueExact(); // will check decimal part too
+ if ((num>32767)|(num<(-32768)))
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+this.toString());
+ return (short)num;
+ }
+
+ /**
+ * Returns the sign of this <code>BigDecimal</code>, as an
+ * <code>int</code>.
+ * This returns the <i>signum</i> function value that represents the
+ * sign of this <code>BigDecimal</code>.
+ * That is, -1 if the <code>BigDecimal</code> is negative, 0 if it is
+ * numerically equal to zero, or 1 if it is positive.
+ *
+ * @return An <code>int</code> which is -1 if the
+ * <code>BigDecimal</code> is negative, 0 if it is
+ * numerically equal to zero, or 1 if it is positive.
+ * @stable ICU 2.0
+ */
+
+ public int signum(){
+ return (int)this.ind; // [note this assumes values for ind.]
+ }
+
+//#if defined(FOUNDATION10)
+//#else
+ /**
+ * Converts this <code>BigDecimal</code> to a
+ * <code>java.math.BigDecimal</code>.
+ * <p>
+ * This is an exact conversion; the result is the same as if the
+ * <code>BigDecimal</code> were formatted as a plain number without
+ * any rounding or exponent and then the
+ * <code>java.math.BigDecimal(java.lang.String)</code> constructor
+ * were used to construct the result.
+ * <p>
+ * <i>(Note: this method is provided only in the
+ * <code>com.ibm.icu.math</code> version of the BigDecimal class.
+ * It would not be present in a <code>java.math</code> version.)</i>
+ *
+ * @return The <code>java.math.BigDecimal</code> equal in value
+ * to this <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public java.math.BigDecimal toBigDecimal(){
+ return new java.math.BigDecimal(this.unscaledValue(),this.scale());
+ }
+//#endif
+
+ /**
+ * Converts this <code>BigDecimal</code> to a
+ * <code>java.math.BigInteger</code>.
+ * <p>
+ * Any decimal part is truncated (discarded).
+ * If an exception is desired should the decimal part be non-zero,
+ * use {@link #toBigIntegerExact()}.
+ *
+ * @return The <code>java.math.BigInteger</code> equal in value
+ * to the integer part of this <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public java.math.BigInteger toBigInteger(){
+ com.ibm.icu.math.BigDecimal res=null;
+ int newlen=0;
+ byte newmant[]=null;
+ {/*select*/
+ if ((exp>=0)&(form==com.ibm.icu.math.MathContext.PLAIN))
+ res=this; // can layout simply
+ else if (exp>=0)
+ {
+ res=clone(this); // safe copy
+ res.form=(byte)com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
+ }
+ else{
+ { // exp<0; scale to be truncated
+ // we could use divideInteger, but we may as well be quicker
+ if (((int)-this.exp)>=this.mant.length)
+ res=ZERO; // all blows away
+ else
+ {
+ res=clone(this); // safe copy
+ newlen=res.mant.length+res.exp;
+ newmant=new byte[newlen]; // [shorter]
+ java.lang.System.arraycopy((java.lang.Object)res.mant,0,(java.lang.Object)newmant,0,newlen);
+ res.mant=newmant;
+ res.form=(byte)com.ibm.icu.math.MathContext.PLAIN;
+ res.exp=0;
+ }
+ }
+ }
+ }
+ return new BigInteger(new java.lang.String(res.layout()));
+ }
+
+ /**
+ * Converts this <code>BigDecimal</code> to a
+ * <code>java.math.BigInteger</code>.
+ * <p>
+ * An exception is thrown if the decimal part (if any) is non-zero.
+ *
+ * @return The <code>java.math.BigInteger</code> equal in value
+ * to the integer part of this <code>BigDecimal</code>.
+ * @throws ArithmeticException if <code>this</code> has a non-zero
+ * decimal part.
+ * @stable ICU 2.0
+ */
+
+ public java.math.BigInteger toBigIntegerExact(){
+ /* test any trailing decimal part */
+ if (exp<0)
+ { // possible decimal part
+ /* all decimal places must be 0; note exp<0 */
+ if ((!(allzero(mant,mant.length+exp))))
+ throw new java.lang.ArithmeticException("Decimal part non-zero:"+" "+this.toString());
+ }
+ return toBigInteger();
+ }
+
+ /**
+ * Returns the <code>BigDecimal</code> as a character array.
+ * The result of this method is the same as using the
+ * sequence <code>toString().toCharArray()</code>, but avoids creating
+ * the intermediate <code>String</code> and <code>char[]</code>
+ * objects.
+ *
+ * @return The <code>char[]</code> array corresponding to this
+ * <code>BigDecimal</code>.
+ * @stable ICU 2.0
+ */
+
+ public char[] toCharArray(){
+ return layout();
+ }
+
+ /**
+ * Returns the <code>BigDecimal</code> as a <code>String</code>.
+ * This returns a <code>String</code> that exactly represents this
+ * <code>BigDecimal</code>, as defined in the decimal documentation
+ * (see {@link BigDecimal class header}).
+ * <p>
+ * By definition, using the {@link #BigDecimal(String)} constructor
+ * on the result <code>String</code> will create a
+ * <code>BigDecimal</code> that is exactly equal to the original
+ * <code>BigDecimal</code>.
+ *
+ * @return The <code>String</code> exactly corresponding to this
+ * <code>BigDecimal</code>.
+ * @see #format(int, int)
+ * @see #format(int, int, int, int, int, int)
+ * @see #toCharArray()
+ * @stable ICU 2.0
+ */
+
+ public java.lang.String toString(){
+ return new java.lang.String(layout());
+ }
+
+ /**
+ * Returns the number as a <code>BigInteger</code> after removing the
+ * scale.
+ * That is, the number is expressed as a plain number, any decimal
+ * point is then removed (retaining the digits of any decimal part),
+ * and the result is then converted to a <code>BigInteger</code>.
+ *
+ * @return The <code>java.math.BigInteger</code> equal in value to
+ * this <code>BigDecimal</code> multiplied by ten to the
+ * power of <code>this.scale()</code>.
+ * @stable ICU 2.0
+ */
+
+ public java.math.BigInteger unscaledValue(){
+ com.ibm.icu.math.BigDecimal res=null;
+ if (exp>=0)
+ res=this;
+ else
+ {
+ res=clone(this); // safe copy
+ res.exp=0; // drop scale
+ }
+ return res.toBigInteger();
+ }
+
+ /**
+ * Translates a <code>double</code> to a <code>BigDecimal</code>.
+ * <p>
+ * Returns a <code>BigDecimal</code> which is the decimal
+ * representation of the 64-bit signed binary floating point
+ * parameter. If the parameter is infinite, or is not a number (NaN),
+ * a <code>NumberFormatException</code> is thrown.
+ * <p>
+ * The number is constructed as though <code>num</code> had been
+ * converted to a <code>String</code> using the
+ * <code>Double.toString()</code> method and the
+ * {@link #BigDecimal(java.lang.String)} constructor had then been used.
+ * This is typically not an exact conversion.
+ *
+ * @param dub The <code>double</code> to be translated.
+ * @return The <code>BigDecimal</code> equal in value to
+ * <code>dub</code>.
+ * @throws NumberFormatException if the parameter is infinite or
+ * not a number.
+ * @stable ICU 2.0
+ */
+
+ public static com.ibm.icu.math.BigDecimal valueOf(double dub){
+ // Reminder: a zero double returns '0.0', so we cannot fastpath to
+ // use the constant ZERO. This might be important enough to justify
+ // a factory approach, a cache, or a few private constants, later.
+ return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());
+ }
+
+ /**
+ * Translates a <code>long</code> to a <code>BigDecimal</code>.
+ * That is, returns a plain <code>BigDecimal</code> whose value is
+ * equal to the given <code>long</code>.
+ *
+ * @param lint The <code>long</code> to be translated.
+ * @return The <code>BigDecimal</code> equal in value to
+ * <code>lint</code>.
+ * @stable ICU 2.0
+ */
+
+ public static com.ibm.icu.math.BigDecimal valueOf(long lint){
+ return valueOf(lint,0);
+ }
+
+ /**
+ * Translates a <code>long</code> to a <code>BigDecimal</code> with a
+ * given scale.
+ * That is, returns a plain <code>BigDecimal</code> whose unscaled
+ * value is equal to the given <code>long</code>, adjusted by the
+ * second parameter, <code>scale</code>.
+ * <p>
+ * The result is given by:
+ * <p><code>
+ * (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale)))
+ * </code>
+ * <p>
+ * A <code>NumberFormatException</code> is thrown if <code>scale</code>
+ * is negative.
+ *
+ * @param lint The <code>long</code> to be translated.
+ * @param scale The <code>int</code> scale to be applied.
+ * @return The <code>BigDecimal</code> equal in value to
+ * <code>lint</code>.
+ * @throws NumberFormatException if the scale is negative.
+ * @stable ICU 2.0
+ */
+
+ public static com.ibm.icu.math.BigDecimal valueOf(long lint,int scale){
+ com.ibm.icu.math.BigDecimal res=null;
+ {/*select*/
+ if (lint==0)
+ res=ZERO;
+ else if (lint==1)
+ res=ONE;
+ else if (lint==10)
+ res=TEN;
+ else{
+ res=new com.ibm.icu.math.BigDecimal(lint);
+ }
+ }
+ if (scale==0)
+ return res;
+ if (scale<0)
+ throw new java.lang.NumberFormatException("Negative scale:"+" "+scale);
+ res=clone(res); // safe copy [do not mutate]
+ res.exp=(int)-scale; // exponent is -scale
+ return res;
+ }
+
+ /* ---------------------------------------------------------------- */
+ /* Private methods */
+ /* ---------------------------------------------------------------- */
+
+ /* <sgml> Return char array value of a BigDecimal (conversion from
+ BigDecimal to laid-out canonical char array).
+ <p>The mantissa will either already have been rounded (following an
+ operation) or will be of length appropriate (in the case of
+ construction from an int, for example).
+ <p>We must not alter the mantissa, here.
+ <p>'form' describes whether we are to use exponential notation (and
+ if so, which), or if we are to lay out as a plain/pure numeric.
+ </sgml> */
+
+ private char[] layout(){
+ char cmant[];
+ int i=0;
+ java.lang.StringBuffer sb=null;
+ int euse=0;
+ int sig=0;
+ char csign=0;
+ char rec[]=null;
+ int needsign;
+ int mag;
+ int len=0;
+ cmant=new char[mant.length]; // copy byte[] to a char[]
+ {int $18=mant.length;i=0;for(;$18>0;$18--,i++){
+ cmant[i]=(char)(mant[i]+((int)('0')));
+ }
+ }/*i*/
+
+ if (form!=com.ibm.icu.math.MathContext.PLAIN)
+ {/* exponential notation needed */
+ sb=new java.lang.StringBuffer(cmant.length+15); // -x.xxxE+999999999
+ if (ind==isneg)
+ sb.append('-');
+ euse=(exp+cmant.length)-1; // exponent to use
+ /* setup sig=significant digits and copy to result */
+ if (form==com.ibm.icu.math.MathContext.SCIENTIFIC)
+ { // [default]
+ sb.append(cmant[0]); // significant character
+ if (cmant.length>1) // have decimal part
+ sb.append('.').append(cmant,1,cmant.length-1);
+ }
+ else
+ {do{
+ sig=euse%3; // common
+ if (sig<0)
+ sig=3+sig; // negative exponent
+ euse=euse-sig;
+ sig++;
+ if (sig>=cmant.length)
+ { // zero padding may be needed
+ sb.append(cmant,0,cmant.length);
+ {int $19=sig-cmant.length;for(;$19>0;$19--){
+ sb.append('0');
+ }
+ }
+ }
+ else
+ { // decimal point needed
+ sb.append(cmant,0,sig).append('.').append(cmant,sig,cmant.length-sig);
+ }
+ }while(false);}/*engineering*/
+ if (euse!=0)
+ {
+ if (euse<0)
+ {
+ csign='-';
+ euse=(int)-euse;
+ }
+ else
+ csign='+';
+ sb.append('E').append(csign).append(euse);
+ }
+ rec=new char[sb.length()];
+ Utility.getChars(sb, 0,sb.length(),rec,0);
+ return rec;
+ }
+
+ /* Here for non-exponential (plain) notation */
+ if (exp==0)
+ {/* easy */
+ if (ind>=0)
+ return cmant; // non-negative integer
+ rec=new char[cmant.length+1];
+ rec[0]='-';
+ java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,1,cmant.length);
+ return rec;
+ }
+
+ /* Need a '.' and/or some zeros */
+ needsign=(int)((ind==isneg)?1:0); // space for sign? 0 or 1
+
+ /* MAG is the position of the point in the mantissa (index of the
+ character it follows) */
+ mag=exp+cmant.length;
+
+ if (mag<1)
+ {/* 0.00xxxx form */
+ len=(needsign+2)-exp; // needsign+2+(-mag)+cmant.length
+ rec=new char[len];
+ if (needsign!=0)
+ rec[0]='-';
+ rec[needsign]='0';
+ rec[needsign+1]='.';
+ {int $20=(int)-mag;i=needsign+2;for(;$20>0;$20--,i++){ // maybe none
+ rec[i]='0';
+ }
+ }/*i*/
+ java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,(needsign+2)-mag,cmant.length);
+ return rec;
+ }
+
+ if (mag>cmant.length)
+ {/* xxxx0000 form */
+ len=needsign+mag;
+ rec=new char[len];
+ if (needsign!=0)
+ rec[0]='-';
+ java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,needsign,cmant.length);
+ {int $21=mag-cmant.length;i=needsign+cmant.length;for(;$21>0;$21--,i++){ // never 0
+ rec[i]='0';
+ }
+ }/*i*/
+ return rec;
+ }
+
+ /* decimal point is in the middle of the mantissa */
+ len=(needsign+1)+cmant.length;
+ rec=new char[len];
+ if (needsign!=0)
+ rec[0]='-';
+ java.lang.System.arraycopy((java.lang.Object)cmant,0,(java.lang.Object)rec,needsign,mag);
+ rec[needsign+mag]='.';
+ java.lang.System.arraycopy((java.lang.Object)cmant,mag,(java.lang.Object)rec,(needsign+mag)+1,cmant.length-mag);
+ return rec;
+ }
+
+ /* <sgml> Checks a BigDecimal argument to ensure it's a true integer
+ in a given range.
+ <p>If OK, returns it as an int. </sgml> */
+ // [currently only used by pow]
+
+ private int intcheck(int min,int max){
+ int i;
+ i=this.intValueExact(); // [checks for non-0 decimal part]
+ // Use same message as though intValueExact failed due to size
+ if ((i<min)|(i>max))
+ throw new java.lang.ArithmeticException("Conversion overflow:"+" "+i);
+ return i;
+ }
+
+ /* <sgml> Carry out division operations. </sgml> */
+ /*
+ Arg1 is operation code: D=divide, I=integer divide, R=remainder
+ Arg2 is the rhs.
+ Arg3 is the context.
+ Arg4 is explicit scale iff code='D' or 'I' (-1 if none).
+
+ Underlying algorithm (complications for Remainder function and
+ scaled division are omitted for clarity):
+
+ Test for x/0 and then 0/x
+ Exp =Exp1 - Exp2
+ Exp =Exp +len(var1) -len(var2)
+ Sign=Sign1 * Sign2
+ Pad accumulator (Var1) to double-length with 0's (pad1)
+ Pad Var2 to same length as Var1
+ B2B=1st two digits of var2, +1 to allow for roundup
+ have=0
+ Do until (have=digits+1 OR residue=0)
+ if exp<0 then if integer divide/residue then leave
+ this_digit=0
+ Do forever
+ compare numbers
+ if <0 then leave inner_loop
+ if =0 then (- quick exit without subtract -) do
+ this_digit=this_digit+1; output this_digit
+ leave outer_loop; end
+ Compare lengths of numbers (mantissae):
+ If same then CA=first_digit_of_Var1
+ else CA=first_two_digits_of_Var1
+ mult=ca*10/b2b -- Good and safe guess at divisor
+ if mult=0 then mult=1
+ this_digit=this_digit+mult
+ subtract
+ end inner_loop
+ if have\=0 | this_digit\=0 then do
+ output this_digit
+ have=have+1; end
+ var2=var2/10
+ exp=exp-1
+ end outer_loop
+ exp=exp+1 -- set the proper exponent
+ if have=0 then generate answer=0
+ Return to FINISHED
+ Result defined by MATHV1
+
+ For extended commentary, see DMSRCN.
+ */
+
+ private com.ibm.icu.math.BigDecimal dodivide(char code,com.ibm.icu.math.BigDecimal rhs,com.ibm.icu.math.MathContext set,int scale){
+ com.ibm.icu.math.BigDecimal lhs;
+ int reqdig;
+ int newexp;
+ com.ibm.icu.math.BigDecimal res;
+ int newlen;
+ byte var1[];
+ int var1len;
+ byte var2[];
+ int var2len;
+ int b2b;
+ int have;
+ int thisdigit=0;
+ int i=0;
+ byte v2=0;
+ int ba=0;
+ int mult=0;
+ int start=0;
+ int padding=0;
+ int d=0;
+ byte newvar1[]=null;
+ byte lasthave=0;
+ int actdig=0;
+ byte newmant[]=null;
+
+ if (set.lostDigits)
+ checkdigits(rhs,set.digits);
+ lhs=this; // name for clarity
+
+ // [note we must have checked lostDigits before the following checks]
+ if (rhs.ind==0)
+ throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
+ if (lhs.ind==0)
+ { // 0/x => 0 [possibly with .0s]
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ return ZERO;
+ if (scale==(-1))
+ return lhs;
+ return lhs.setScale(scale);
+ }
+
+ /* Prepare numbers according to BigDecimal rules */
+ reqdig=set.digits; // local copy (heavily used)
+ if (reqdig>0)
+ {
+ if (lhs.mant.length>reqdig)
+ lhs=clone(lhs).round(set);
+ if (rhs.mant.length>reqdig)
+ rhs=clone(rhs).round(set);
+ }
+ else
+ {/* scaled divide */
+ if (scale==(-1))
+ scale=lhs.scale();
+ // set reqdig to be at least large enough for the computation
+ reqdig=lhs.mant.length; // base length
+ // next line handles both positive lhs.exp and also scale mismatch
+ if (scale!=((int)-lhs.exp))
+ reqdig=(reqdig+scale)+lhs.exp;
+ reqdig=(reqdig-((rhs.mant.length-1)))-rhs.exp; // reduce by RHS effect
+ if (reqdig<lhs.mant.length)
+ reqdig=lhs.mant.length; // clamp
+ if (reqdig<rhs.mant.length)
+ reqdig=rhs.mant.length; // ..
+ }
+
+ /* precalculate exponent */
+ newexp=((lhs.exp-rhs.exp)+lhs.mant.length)-rhs.mant.length;
+ /* If new exponent -ve, then some quick exits are possible */
+ if (newexp<0)
+ if (code!='D')
+ {
+ if (code=='I')
+ return ZERO; // easy - no integer part
+ /* Must be 'R'; remainder is [finished clone of] input value */
+ return clone(lhs).finish(set,false);
+ }
+
+ /* We need slow division */
+ res=new com.ibm.icu.math.BigDecimal(); // where we'll build result
+ res.ind=(byte)(lhs.ind*rhs.ind); // final sign (for D/I)
+ res.exp=newexp; // initial exponent (for D/I)
+ res.mant=new byte[reqdig+1]; // where build the result
+
+ /* Now [virtually pad the mantissae with trailing zeros */
+ // Also copy the LHS, which will be our working array
+ newlen=(reqdig+reqdig)+1;
+ var1=extend(lhs.mant,newlen); // always makes longer, so new safe array
+ var1len=newlen; // [remaining digits are 0]
+
+ var2=rhs.mant;
+ var2len=newlen;
+
+ /* Calculate first two digits of rhs (var2), +1 for later estimations */
+ b2b=(var2[0]*10)+1;
+ if (var2.length>1)
+ b2b=b2b+var2[1];
+
+ /* start the long-division loops */
+ have=0;
+ {outer:for(;;){
+ thisdigit=0;
+ /* find the next digit */
+ {inner:for(;;){
+ if (var1len<var2len)
+ break inner; // V1 too low
+ if (var1len==var2len)
+ { // compare needed
+ {compare:do{ // comparison
+ {int $22=var1len;i=0;for(;$22>0;$22--,i++){
+ // var1len is always <= var1.length
+ if (i<var2.length)
+ v2=var2[i];
+ else
+ v2=(byte)0;
+ if (var1[i]<v2)
+ break inner; // V1 too low
+ if (var1[i]>v2)
+ break compare; // OK to subtract
+ }
+ }/*i*/
+ /* reach here if lhs and rhs are identical; subtraction will
+ increase digit by one, and the residue will be 0 so we
+ are done; leave the loop with residue set to 0 (in case
+ code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is
+ being checked) */
+ thisdigit++;
+ res.mant[have]=(byte)thisdigit;
+ have++;
+ var1[0]=(byte)0; // residue to 0 [this is all we'll test]
+ // var1len=1 -- [optimized out]
+ break outer;
+ }while(false);}/*compare*/
+ /* prepare for subtraction. Estimate BA (lengths the same) */
+ ba=(int)var1[0]; // use only first digit
+ } // lengths the same
+ else
+ {/* lhs longer than rhs */
+ /* use first two digits for estimate */
+ ba=var1[0]*10;
+ if (var1len>1)
+ ba=ba+var1[1];
+ }
+ /* subtraction needed; V1>=V2 */
+ mult=(ba*10)/b2b;
+ if (mult==0)
+ mult=1;
+ thisdigit=thisdigit+mult;
+ // subtract; var1 reusable
+ var1=byteaddsub(var1,var1len,var2,var2len,(int)-mult,true);
+ if (var1[0]!=0)
+ continue inner; // maybe another subtract needed
+ /* V1 now probably has leading zeros, remove leading 0's and try
+ again. (It could be longer than V2) */
+ {int $23=var1len-2;start=0;start:for(;start<=$23;start++){
+ if (var1[start]!=0)
+ break start;
+ var1len--;
+ }
+ }/*start*/
+ if (start==0)
+ continue inner;
+ // shift left
+ java.lang.System.arraycopy((java.lang.Object)var1,start,(java.lang.Object)var1,0,var1len);
+ }
+ }/*inner*/
+
+ /* We have the next digit */
+ if ((have!=0)|(thisdigit!=0))
+ { // put the digit we got
+ res.mant[have]=(byte)thisdigit;
+ have++;
+ if (have==(reqdig+1))
+ break outer; // we have all we need
+ if (var1[0]==0)
+ break outer; // residue now 0
+ }
+ /* can leave now if a scaled divide and exponent is small enough */
+ if (scale>=0)
+ if (((int)-res.exp)>scale)
+ break outer;
+ /* can leave now if not Divide and no integer part left */
+ if (code!='D')
+ if (res.exp<=0)
+ break outer;
+ res.exp=res.exp-1; // reduce the exponent
+ /* to get here, V1 is less than V2, so divide V2 by 10 and go for
+ the next digit */
+ var2len--;
+ }
+ }/*outer*/
+
+ /* here when we have finished dividing, for some reason */
+ // have is the number of digits we collected in res.mant
+ if (have==0)
+ have=1; // res.mant[0] is 0; we always want a digit
+
+ if ((code=='I')|(code=='R'))
+ {/* check for integer overflow needed */
+ if ((have+res.exp)>reqdig)
+ throw new java.lang.ArithmeticException("Integer overflow");
+
+ if (code=='R')
+ {do{
+ /* We were doing Remainder -- return the residue */
+ if (res.mant[0]==0) // no integer part was found
+ return clone(lhs).finish(set,false); // .. so return lhs, canonical
+ if (var1[0]==0)
+ return ZERO; // simple 0 residue
+ res.ind=lhs.ind; // sign is always as LHS
+ /* Calculate the exponent by subtracting the number of padding zeros
+ we added and adding the original exponent */
+ padding=((reqdig+reqdig)+1)-lhs.mant.length;
+ res.exp=(res.exp-padding)+lhs.exp;
+
+ /* strip insignificant padding zeros from residue, and create/copy
+ the resulting mantissa if need be */
+ d=var1len;
+ {i=d-1;i:for(;i>=1;i--){if(!((res.exp<lhs.exp)&(res.exp<rhs.exp)))break;
+ if (var1[i]!=0)
+ break i;
+ d--;
+ res.exp=res.exp+1;
+ }
+ }/*i*/
+ if (d<var1.length)
+ {/* need to reduce */
+ newvar1=new byte[d];
+ java.lang.System.arraycopy((java.lang.Object)var1,0,(java.lang.Object)newvar1,0,d); // shorten
+ var1=newvar1;
+ }
+ res.mant=var1;
+ return res.finish(set,false);
+ }while(false);}/*remainder*/
+ }
+
+ else
+ {/* 'D' -- no overflow check needed */
+ // If there was a residue then bump the final digit (iff 0 or 5)
+ // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
+ // ROUND_UNNECESSARY checks (etc.) later.
+ // [if we finished early, the residue will be 0]
+ if (var1[0]!=0)
+ { // residue not 0
+ lasthave=res.mant[have-1];
+ if (((lasthave%5))==0)
+ res.mant[have-1]=(byte)(lasthave+1);
+ }
+ }
+
+ /* Here for Divide or Integer Divide */
+ // handle scaled results first ['I' always scale 0, optional for 'D']
+ if (scale>=0)
+ {do{
+ // say 'scale have res.exp len' scale have res.exp res.mant.length
+ if (have!=res.mant.length)
+ // already padded with 0's, so just adjust exponent
+ res.exp=res.exp-((res.mant.length-have));
+ // calculate number of digits we really want [may be 0]
+ actdig=res.mant.length-((((int)-res.exp)-scale));
+ res.round(actdig,set.roundingMode); // round to desired length
+ // This could have shifted left if round (say) 0.9->1[.0]
+ // Repair if so by adding a zero and reducing exponent
+ if (res.exp!=((int)-scale))
+ {
+ res.mant=extend(res.mant,res.mant.length+1);
+ res.exp=res.exp-1;
+ }
+ return res.finish(set,true); // [strip if not PLAIN]
+ }while(false);}/*scaled*/
+
+ // reach here only if a non-scaled
+ if (have==res.mant.length)
+ { // got digits+1 digits
+ res.round(set);
+ have=reqdig;
+ }
+ else
+ {/* have<=reqdig */
+ if (res.mant[0]==0)
+ return ZERO; // fastpath
+ // make the mantissa truly just 'have' long
+ // [we could let finish do this, during strip, if we adjusted
+ // the exponent; however, truncation avoids the strip loop]
+ newmant=new byte[have]; // shorten
+ java.lang.System.arraycopy((java.lang.Object)res.mant,0,(java.lang.Object)newmant,0,have);
+ res.mant=newmant;
+ }
+ return res.finish(set,true);
+ }
+
+
+ /* <sgml> Report a conversion exception. </sgml> */
+
+ private void bad(char s[]){
+ throw new java.lang.NumberFormatException("Not a number:"+" "+java.lang.String.valueOf(s));
+ }
+
+ /* <sgml> Report a bad argument to a method. </sgml>
+ Arg1 is method name
+ Arg2 is argument position
+ Arg3 is what was found */
+
+ private void badarg(java.lang.String name,int pos,java.lang.String value){
+ throw new java.lang.IllegalArgumentException("Bad argument"+" "+pos+" "+"to"+" "+name+":"+" "+value);
+ }
+
+ /* <sgml> Extend byte array to given length, padding with 0s. If no
+ extension is required then return the same array. </sgml>
+
+ Arg1 is the source byte array
+ Arg2 is the new length (longer)
+ */
+
+ private static final byte[] extend(byte inarr[],int newlen){
+ byte newarr[];
+ if (inarr.length==newlen)
+ return inarr;
+ newarr=new byte[newlen];
+ java.lang.System.arraycopy((java.lang.Object)inarr,0,(java.lang.Object)newarr,0,inarr.length);
+ // 0 padding is carried out by the JVM on allocation initialization
+ return newarr;
+ }
+
+ /* <sgml> Add or subtract two >=0 integers in byte arrays
+ <p>This routine performs the calculation:
+ <pre>
+ C=A+(B*M)
+ </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
+ non-negative.
+
+ Leading zeros are not removed after a subtraction. The result is
+ either the same length as the longer of A and B, or 1 longer than
+ that (if a carry occurred).
+
+ A is not altered unless Arg6 is 1.
+ B is never altered.
+
+ 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 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)
+
+ This routine is severely performance-critical; *any* change here
+ must be measured (timed) to assure no performance degradation.
+ */
+ // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
+ // 1997.10.05 -- changed to byte arrays (from char arrays)
+ // 1998.07.01 -- changed to allow destructive reuse of LHS
+ // 1998.07.01 -- changed to allow virtual lengths for the arrays
+ // 1998.12.29 -- use lookaside for digit/carry calculation
+ // 1999.08.07 -- avoid multiply when mult=1, and make db an int
+ // 1999.12.22 -- special case m=-1, also drop 0 special case
+
+ private static final byte[] byteaddsub(byte a[],int avlen,byte b[],int bvlen,int m,boolean reuse){
+ int alength;
+ int blength;
+ int ap;
+ int bp;
+ int maxarr;
+ byte reb[];
+ boolean quickm;
+ int digit;
+ int op=0;
+ int dp90=0;
+ byte newarr[];
+ int i=0;
+
+
+
+
+ // We'll usually be right if we assume no carry
+ alength=a.length; // physical lengths
+ blength=b.length; // ..
+ ap=avlen-1; // -> final (rightmost) digit
+ bp=bvlen-1; // ..
+ maxarr=bp;
+ if (maxarr<ap)
+ maxarr=ap;
+ reb=(byte[])null; // result byte array
+ if (reuse)
+ if ((maxarr+1)==alength)
+ reb=a; // OK to reuse A
+ if (reb==null)
+ reb=new byte[maxarr+1]; // need new array
+
+ quickm=false; // 1 if no multiply needed
+ if (m==1)
+ quickm=true; // most common
+ else
+ if (m==(-1))
+ quickm=true; // also common
+
+ digit=0; // digit, with carry or borrow
+ {op=maxarr;op:for(;op>=0;op--){
+ if (ap>=0)
+ {
+ if (ap<alength)
+ digit=digit+a[ap]; // within A
+ ap--;
+ }
+ if (bp>=0)
+ {
+ if (bp<blength)
+ { // within B
+ if (quickm)
+ {
+ if (m>0)
+ digit=digit+b[bp]; // most common
+ else
+ digit=digit-b[bp]; // also common
+ }
+ else
+ digit=digit+(b[bp]*m);
+ }
+ bp--;
+ }
+ /* result so far (digit) could be -90 through 99 */
+ if (digit<10)
+ if (digit>=0)
+ {do{ // 0-9
+ reb[op]=(byte)digit;
+ digit=0; // no carry
+ continue op;
+ }while(false);}/*quick*/
+ dp90=digit+90;
+ reb[op]=bytedig[dp90]; // this digit
+ digit=bytecar[dp90]; // carry or borrow
+ }
+ }/*op*/
+
+ if (digit==0)
+ return reb; // no carry
+ // following line will become an Assert, later
+ // if digit<0 then signal ArithmeticException("internal.error ["digit"]")
+
+ /* We have carry -- need to make space for the extra digit */
+ newarr=(byte[])null;
+ if (reuse)
+ if ((maxarr+2)==a.length)
+ newarr=a; // OK to reuse A
+ if (newarr==null)
+ newarr=new byte[maxarr+2];
+ newarr[0]=(byte)digit; // the carried digit ..
+ // .. and all the rest [use local loop for short numbers]
+ if (maxarr<10)
+ {int $24=maxarr+1;i=0;for(;$24>0;$24--,i++){
+ newarr[i+1]=reb[i];
+ }
+ }/*i*/
+ else
+ java.lang.System.arraycopy((java.lang.Object)reb,0,(java.lang.Object)newarr,1,maxarr+1);
+ return newarr;
+ }
+
+ /* <sgml> Initializer for digit array properties (lookaside). </sgml>
+ Returns the digit array, and initializes the carry array. */
+
+ private static final byte[] diginit(){
+ byte work[];
+ int op=0;
+ int digit=0;
+ work=new byte[(90+99)+1];
+ {op=0;op:for(;op<=(90+99);op++){
+ digit=op-90;
+ if (digit>=0)
+ {
+ work[op]=(byte)(digit%10);
+ bytecar[op]=(byte)(digit/10); // calculate carry
+ continue op;
+ }
+ // borrowing...
+ digit=digit+100; // yes, this is right [consider -50]
+ work[op]=(byte)(digit%10);
+ bytecar[op]=(byte)((digit/10)-10); // calculate borrow [NB: - after %]
+ }
+ }/*op*/
+ return work;
+ }
+
+ /* <sgml> Create a copy of BigDecimal object for local use.
+ <p>This does NOT make a copy of the mantissa array.
+ </sgml>
+ Arg1 is the BigDecimal to clone (non-null)
+ */
+
+ private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec){
+ com.ibm.icu.math.BigDecimal copy;
+ copy=new com.ibm.icu.math.BigDecimal();
+ copy.ind=dec.ind;
+ copy.exp=dec.exp;
+ copy.form=dec.form;
+ copy.mant=dec.mant;
+ return copy;
+ }
+
+ /* <sgml> Check one or two numbers for lost digits. </sgml>
+ Arg1 is RHS (or null, if none)
+ Arg2 is current DIGITS setting
+ returns quietly or throws an exception */
+
+ private void checkdigits(com.ibm.icu.math.BigDecimal rhs,int dig){
+ if (dig==0)
+ return; // don't check if digits=0
+ // first check lhs...
+ if (this.mant.length>dig)
+ if ((!(allzero(this.mant,dig))))
+ throw new java.lang.ArithmeticException("Too many digits:"+" "+this.toString());
+ if (rhs==null)
+ return; // monadic
+ if (rhs.mant.length>dig)
+ if ((!(allzero(rhs.mant,dig))))
+ throw new java.lang.ArithmeticException("Too many digits:"+" "+rhs.toString());
+ }
+
+ /* <sgml> Round to specified digits, if necessary. </sgml>
+ Arg1 is requested MathContext [with length and rounding mode]
+ returns this, for convenience */
+
+ private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set){
+ return round(set.digits,set.roundingMode);
+ }
+
+ /* <sgml> Round to specified digits, if necessary.
+ Arg1 is requested length (digits to round to)
+ [may be <=0 when called from format, dodivide, etc.]
+ Arg2 is rounding mode
+ returns this, for convenience
+
+ ind and exp are adjusted, but not cleared for a mantissa of zero
+
+ The length of the mantissa returned will be Arg1, except when Arg1
+ is 0, in which case the returned mantissa length will be 1.
+ </sgml>
+ */
+
+ private com.ibm.icu.math.BigDecimal round(int len,int mode){
+ int adjust;
+ int sign;
+ byte oldmant[];
+ boolean reuse=false;
+ byte first=0;
+ int increment;
+ byte newmant[]=null;
+ adjust=mant.length-len;
+ if (adjust<=0)
+ return this; // nowt to do
+
+ exp=exp+adjust; // exponent of result
+ sign=(int)ind; // save [assumes -1, 0, 1]
+ oldmant=mant; // save
+ if (len>0)
+ {
+ // remove the unwanted digits
+ mant=new byte[len];
+ java.lang.System.arraycopy((java.lang.Object)oldmant,0,(java.lang.Object)mant,0,len);
+ reuse=true; // can reuse mantissa
+ first=oldmant[len]; // first of discarded digits
+ }
+ else
+ {/* len<=0 */
+ mant=ZERO.mant;
+ ind=iszero;
+ reuse=false; // cannot reuse mantissa
+ if (len==0)
+ first=oldmant[0];
+ else
+ first=(byte)0; // [virtual digit]
+ }
+
+ // decide rounding adjustment depending on mode, sign, and discarded digits
+ increment=0; // bumper
+ {do{/*select*/
+ if (mode==ROUND_HALF_UP)
+ { // default first [most common]
+ if (first>=5)
+ increment=sign;
+ }
+ else if (mode==ROUND_UNNECESSARY)
+ { // default for setScale()
+ // discarding any non-zero digits is an error
+ if ((!(allzero(oldmant,len))))
+ throw new java.lang.ArithmeticException("Rounding necessary");
+ }
+ else if (mode==ROUND_HALF_DOWN)
+ { // 0.5000 goes down
+ if (first>5)
+ increment=sign;
+ else
+ if (first==5)
+ if ((!(allzero(oldmant,len+1))))
+ increment=sign;
+ }
+ else if (mode==ROUND_HALF_EVEN)
+ { // 0.5000 goes down if left digit even
+ if (first>5)
+ increment=sign;
+ else
+ if (first==5)
+ {
+ if ((!(allzero(oldmant,len+1))))
+ increment=sign;
+ else /* 0.5000 */
+ if ((((mant[mant.length-1])%2))==1)
+ increment=sign;
+ }
+ }
+ else if (mode==ROUND_DOWN){
+ // never increment
+ }else if (mode==ROUND_UP)
+ { // increment if discarded non-zero
+ if ((!(allzero(oldmant,len))))
+ increment=sign;
+ }
+ else if (mode==ROUND_CEILING)
+ { // more positive
+ if (sign>0)
+ if ((!(allzero(oldmant,len))))
+ increment=sign;
+ }
+ else if (mode==ROUND_FLOOR)
+ { // more negative
+ if (sign<0)
+ if ((!(allzero(oldmant,len))))
+ increment=sign;
+ }
+ else{
+ throw new java.lang.IllegalArgumentException("Bad round value:"+" "+mode);
+ }
+ }while(false);}/*modes*/
+
+ if (increment!=0)
+ {do{
+ if (ind==iszero)
+ {
+ // we must not subtract from 0, but result is trivial anyway
+ mant=ONE.mant;
+ ind=(byte)increment;
+ }
+ else
+ {
+ // mantissa is non-0; we can safely add or subtract 1
+ if (ind==isneg)
+ increment=(int)-increment;
+ newmant=byteaddsub(mant,mant.length,ONE.mant,1,increment,reuse);
+ if (newmant.length>mant.length)
+ { // had a carry
+ // drop rightmost digit and raise exponent
+ exp++;
+ // mant is already the correct length
+ java.lang.System.arraycopy((java.lang.Object)newmant,0,(java.lang.Object)mant,0,mant.length);
+ }
+ else
+ mant=newmant;
+ }
+ }while(false);}/*bump*/
+ // rounding can increase exponent significantly
+ if (exp>MaxExp)
+ throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+exp);
+ return this;
+ }
+
+ /* <sgml> Test if rightmost digits are all 0.
+ Arg1 is a mantissa array to test
+ Arg2 is the offset of first digit to check
+ [may be negative; if so, digits to left are 0's]
+ returns 1 if all the digits starting at Arg2 are 0
+
+ Arg2 may be beyond array bounds, in which case 1 is returned
+ </sgml> */
+
+ private static final boolean allzero(byte array[],int start){
+ int i=0;
+ if (start<0)
+ start=0;
+ {int $25=array.length-1;i=start;for(;i<=$25;i++){
+ if (array[i]!=0)
+ return false;
+ }
+ }/*i*/
+ return true;
+ }
+
+ /* <sgml> Carry out final checks and canonicalization
+ <p>
+ This finishes off the current number by:
+ 1. Rounding if necessary (NB: length includes leading zeros)
+ 2. Stripping trailing zeros (if requested and \PLAIN)
+ 3. Stripping leading zeros (always)
+ 4. Selecting exponential notation (if required)
+ 5. Converting a zero result to just '0' (if \PLAIN)
+ In practice, these operations overlap and share code.
+ It always sets form.
+ </sgml>
+ Arg1 is requested MathContext (length to round to, trigger, and FORM)
+ Arg2 is 1 if trailing insignificant zeros should be removed after
+ round (for division, etc.), provided that set.form isn't PLAIN.
+ returns this, for convenience
+ */
+
+ private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set,boolean strip){
+ int d=0;
+ int i=0;
+ byte newmant[]=null;
+ int mag=0;
+ int sig=0;
+ /* Round if mantissa too long and digits requested */
+ if (set.digits!=0)
+ if (this.mant.length>set.digits)
+ this.round(set);
+
+ /* If strip requested (and standard formatting), remove
+ insignificant trailing zeros. */
+ if (strip)
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ {
+ d=this.mant.length;
+ /* see if we need to drop any trailing zeros */
+ {i=d-1;i:for(;i>=1;i--){
+ if (this.mant[i]!=0)
+ break i;
+ d--;
+ exp++;
+ }
+ }/*i*/
+ if (d<this.mant.length)
+ {/* need to reduce */
+ newmant=new byte[d];
+ java.lang.System.arraycopy((java.lang.Object)this.mant,0,(java.lang.Object)newmant,0,d);
+ this.mant=newmant;
+ }
+ }
+
+ form=(byte)com.ibm.icu.math.MathContext.PLAIN; // preset
+
+ /* Now check for leading- and all- zeros in mantissa */
+ {int $26=this.mant.length;i=0;for(;$26>0;$26--,i++){
+ if (this.mant[i]!=0)
+ {
+ // non-0 result; ind will be correct
+ // remove leading zeros [e.g., after subtract]
+ if (i>0)
+ {do{
+ newmant=new byte[this.mant.length-i];
+ java.lang.System.arraycopy((java.lang.Object)this.mant,i,(java.lang.Object)newmant,0,this.mant.length-i);
+ this.mant=newmant;
+ }while(false);}/*delead*/
+ // now determine form if not PLAIN
+ mag=exp+mant.length;
+ if (mag>0)
+ { // most common path
+ if (mag>set.digits)
+ if (set.digits!=0)
+ form=(byte)set.form;
+ if ((mag-1)<=MaxExp)
+ return this; // no overflow; quick return
+ }
+ else
+ if (mag<(-5))
+ form=(byte)set.form;
+ /* check for overflow */
+ mag--;
+ if ((mag<MinExp)|(mag>MaxExp))
+ {overflow:do{
+ // possible reprieve if form is engineering
+ if (form==com.ibm.icu.math.MathContext.ENGINEERING)
+ {
+ sig=mag%3; // leftover
+ if (sig<0)
+ sig=3+sig; // negative exponent
+ mag=mag-sig; // exponent to use
+ // 1999.06.29: second test here must be MaxExp
+ if (mag>=MinExp)
+ if (mag<=MaxExp)
+ break overflow;
+ }
+ throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+mag);
+ }while(false);}/*overflow*/
+ return this;
+ }
+ }
+ }/*i*/
+
+ // Drop through to here only if mantissa is all zeros
+ ind=iszero;
+ {/*select*/
+ if (set.form!=com.ibm.icu.math.MathContext.PLAIN)
+ exp=0; // standard result; go to '0'
+ else if (exp>0)
+ exp=0; // +ve exponent also goes to '0'
+ else{
+ // a plain number with -ve exponent; preserve and check exponent
+ if (exp<MinExp)
+ throw new java.lang.ArithmeticException("Exponent Overflow:"+" "+exp);
+ }
+ }
+ mant=ZERO.mant; // canonical mantissa
+ return this;
+ }
+ }