com.ibm.icu.math.BigDecimal Maven / Gradle / Ivy
Show all versions of icu4j Show documentation
/* 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.lang.UCharacter; /* ------------------------------------------------------------------ */ /* BigDecimal -- Decimal arithmetic for Java */ /* ------------------------------------------------------------------ */ /* Copyright IBM Corporation, 1996-2011. 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)
E' that indicates how the decimal point will be shifted. Thus the; 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 BigDecimal
class implements immutable arbitrary-precision decimal numbers. The methods of the *BigDecimal
class provide operations for fixed and floating point arithmetic, comparison, format * conversions, and hashing. ** As the numbers are decimal, there is an exact correspondence between an instance of a
BigDecimal
object * and itsString
representation; theBigDecimal
class provides direct conversions to and from *String
and character array (char[]
) objects, as well as conversions to and from the Java * primitive types (which may not be exact) andBigInteger
. ** In the descriptions of constructors and methods in this documentation, the value of a
BigDecimal
number * object is shown as the result of invoking thetoString()
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. ** The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also * documented at
http://www2.hursley.ibm.com/decimal
* [This URL will change.] * *Operator methods
** Operations on
BigDecimal
numbers are controlled by a {@link MathContext} object, which provides the * context (precision and other information) for the operation. Methods that can take aMathContext
* parameter implement the standard arithmetic operators forBigDecimal
objects and are known as * operator methods. The default settings provided by the constant {@link MathContext#DEFAULT} (digits=9, * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP
) perform general-purpose floating point * arithmetic to nine digits of precision. TheMathContext
parameter must not benull
. ** Each operator method also has a version provided which does not take a
MathContext
parameter. For this * version of each method, the context settings used aredigits=0, * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP
; these settings perform fixed point arithmetic with * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2. ** For monadic operators, only the optional
MathContext
parameter is present; the operation acts upon the * current object. ** For dyadic operators, a
BigDecimal
parameter is always present; it must not benull
. The * operation acts with the current object being the left-hand operand and theBigDecimal
parameter being * the right-hand operand. ** For example, adding two
BigDecimal
objects referred to by the namesaward
and *extra
could be written as any of: **
* award.add(extra) *
*
award.add(extra, MathContext.DEFAULT) *
award.add(extra, acontext) ** (where
acontext
is aMathContext
object), which would return aBigDecimal
* object whose value is the result of addingaward
andextra
under the appropriate context * settings. ** When a
BigDecimal
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: **
- Results are normally calculated with up to some maximum number of significant digits. For example, if the *
MathContext
parameter for an operation wereMathContext.DEFAULT
then the result would be * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667.
* You can change the default of 9 significant digits by providing the method with a suitableMathContext
* object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled) * arithmetic is indicated by using adigits
setting of 0 (or omitting theMathContext
* parameter).
* Similarly, you can change the algorithm used for rounding from the default "classic" algorithm. *- * In standard arithmetic (that is, when the
form
setting is notPLAIN
), a zero result is * always expressed as the single digit'0'
(that is, with no sign, decimal point, or exponent part). *- * 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).
* So, for example: **
* new BigDecimal("2.40").add( new BigDecimal("2")) => "4.40" *
*
new BigDecimal("2.40").subtract(new BigDecimal("2")) => "0.40" *
new BigDecimal("2.40").multiply(new BigDecimal("2")) => "4.80" *
new BigDecimal("2.40").divide( new BigDecimal("2"), def) => "1.2" ** where the value on the right of the
=>
would be the result of the operation, expressed as a *String
, anddef
(in this and following examples) refers toMathContext.DEFAULT
* ). 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. *- * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of *
digits
(the default is 9 digits). If the number of places needed before the decimal point exceeds the *digits
setting, or the absolute value of the number is less than0.000001
, then the number * will be expressed in exponential notation; thus **
* new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def) *
** results in
1E+12
instead of1000000000000
, and **
* new BigDecimal("1").divide(new BigDecimal("3E+10"), def) *
** results in
3.33333333E-11
instead of0.0000000000333333333
. ** The form of the exponential notation (scientific or engineering) is determined by the
form
setting. ** * The names of methods in this class follow the conventions established by
java.lang.Number
, *java.math.BigInteger
, andjava.math.BigDecimal
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 BigDecimal
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 /** * TheBigDecimal
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 /** * TheBigDecimal
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: **
* * @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: *- ispos -- the number is positive
- iszero -- the number is zero
- isneg -- the number is negative *
*
*- MathContext.PLAIN -- no exponent needed
- MathContext.SCIENTIFIC -- scientific notation required
- * MathContext.ENGINEERING -- engineering notation required *
* 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. *
* Once constructed, this may become shared between several BigDecimal objects, so must not be altered. *
* For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9. *
* 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. *
* For fixed point arithmetic, scale is
-exp
, 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 */ /* ---------------------------------------------------------------- */ /** * Constructs aBigDecimal
object from ajava.math.BigDecimal
. ** Constructs a
BigDecimal
as though the parameter had been represented as aString
(using * itstoString
method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used. * The parameter must not benull
. ** (Note: this constructor is provided only in the
com.ibm.icu.math
version of the BigDecimal class. * It would not be present in ajava.math
version.) * * @param bd TheBigDecimal
to be translated. * @stable ICU 2.0 */ public BigDecimal(java.math.BigDecimal bd) { this(bd.toString()); return; } /** * Constructs aBigDecimal
object from aBigInteger
, with scale 0. ** Constructs a
BigDecimal
which is the exact decimal representation of theBigInteger
, * with a scale of zero. The value of theBigDecimal
is identical to the value of theBigInteger *
. The parameter must not benull
. ** The
BigDecimal
will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the *BigInteger
is negative. A leading zero will be present only if theBigInteger
is zero. * * @param bi TheBigInteger
to be converted. * @stable ICU 2.0 */ public BigDecimal(java.math.BigInteger bi) { this(bi.toString(10)); return; } // exp remains 0 /** * Constructs aBigDecimal
object from aBigInteger
and a scale. ** Constructs a
BigDecimal
which is the exact decimal representation of theBigInteger
, * scaled by the second parameter, which may not be negative. The value of theBigDecimal
is the* BigInteger
divided by ten to the power of the scale. TheBigInteger
parameter must not be *null
. ** The
BigDecimal
will contain only decimal digits, (with an embedded decimal point followed by* scale
decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the* BigInteger
is negative. A leading zero will be present only if theBigInteger
is zero. * * @param bi TheBigInteger
to be converted. * @param scale Theint
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 = -scale; // exponent is -scale return; } /** * Constructs aBigDecimal
object from an array of characters. ** Constructs a
BigDecimal
as though aString
had been constructed from the character * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be *null
. ** Using this constructor is faster than using the
BigDecimal(String)
constructor if the string is * already available in character array form. * * @param inchars Thechar[]
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 aBigDecimal
object from an array of characters. ** Constructs a
BigDecimal
as though aString
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 benull
, and the subarray must be wholly contained within it. ** Using this constructor is faster than using the
BigDecimal(String)
constructor if the string is * already available within a character array. * * @param inchars Thechar[]
array containing the number to be converted. * @param offset Theint
offset into the array of the start of the number to be converted. * @param length Theint
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 = -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 aBigDecimal
object directly from adouble
. ** Constructs a
BigDecimal
which is the exact decimal representation of the 64-bit signed binary * floating point parameter. ** Note that this constructor it an exact conversion; it does not give the same result as converting
num *
to aString
using theDouble.toString()
method and then using the * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)} * method to construct aBigDecimal
from adouble
. * * @param num Thedouble
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 this((new java.math.BigDecimal(num)).toString()); return; } /** * Constructs aBigDecimal
object directly from aint
. ** Constructs a
BigDecimal
which is the exact decimal representation of the 32-bit signed binary * integer parameter. TheBigDecimal
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 Theint
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) -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 = -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 aBigDecimal
object directly from along
. ** Constructs a
BigDecimal
which is the exact decimal representation of the 64-bit signed binary * integer parameter. TheBigDecimal
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 Thelong
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 = -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 aBigDecimal
object from aString
. ** Constructs a
BigDecimal
from the parameter, which must not benull
and must represent a * valid number, as described formally in the documentation referred to {@link BigDecimal above}. ** In summary, numbers in
String
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. ** Some valid strings from which a
BigDecimal
might be constructed are: * ** * "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 * *** (Exponential notation means that the number includes an optional sign and a power of ten following an * '
"4E+9"
above is * just a short way of writing4000000000
, and the"0.73e-7"
is short for* 0.000000073
.) ** The
BigDecimal
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 ane
or anE
), then theBigDecimal *
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. ** Any digits in the parameter must be decimal; that is,
Character.digit(c, 10)
(where c * is the character in question) would not return -1. * * @param string TheString
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; } /*Make a default BigDecimal object for local use. */ private BigDecimal() { super(); return; } /* ---------------------------------------------------------------- */ /* Operator methods [methods which take a context parameter] */ /* ---------------------------------------------------------------- */ /** * Returns a plainBigDecimal
whose value is the absolute value of thisBigDecimal
. ** The same as {@link #abs(MathContext)}, where the context is
new MathContext(0, MathContext.PLAIN)
. ** The length of the decimal part (the scale) of the result will be
this.scale()
* * @return ABigDecimal
whose value is the absolute value of thisBigDecimal
. * @stable ICU 2.0 */ public com.ibm.icu.math.BigDecimal abs() { return this.abs(plainMC); } /** * Returns aBigDecimal
whose value is the absolute value of thisBigDecimal
. ** 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
MathContext
arithmetic settings. * @return ABigDecimal
whose value is the absolute value of thisBigDecimal
. * @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 plainBigDecimal
whose value isthis+rhs
, using fixed point arithmetic. ** The same as {@link #add(BigDecimal, MathContext)}, where the
BigDecimal
isrhs
, and the * context isnew MathContext(0, MathContext.PLAIN)
. ** 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
BigDecimal
for the right hand side of the addition. * @return ABigDecimal
whose value isthis+rhs
, 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 aBigDecimal
whose value isthis+rhs
. ** Implements the addition (
+
) operator (as defined in the decimal documentation, see * {@link BigDecimal class header}), and returns the result as aBigDecimal
object. * * @param rhs TheBigDecimal
for the right hand side of the addition. * @param set TheMathContext
arithmetic settings. * @return ABigDecimal
whose value isthis+rhs
. * @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 thisBigDecimal
to another, using unlimited precision. ** The same as {@link #compareTo(BigDecimal, MathContext)}, where the
BigDecimal
isrhs
, * and the context isnew MathContext(0, MathContext.PLAIN)
. * * @param rhs TheBigDecimal
for the right hand side of the comparison. * @return Anint
whose value is -1, 0, or 1 asthis
is numerically less than, equal to, * or greater thanrhs
. * @stable ICU 2.0 */ public int compareTo(com.ibm.icu.math.BigDecimal rhs) { return this.compareTo(rhs, plainMC); } /** * Compares thisBigDecimal
to another. ** Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}), * and returns a result of type
int
. ** The result will be: *
-1 | if the current object is less than the first parameter | *
0 | if the current object is equal to the first parameter | *
1 | if the current object is greater than the first parameter. | *
* A {@link #compareTo(BigDecimal)} method is also provided.
*
* @param rhs The BigDecimal
for the right hand side of the comparison.
* @param set The MathContext
arithmetic settings.
* @return An int
whose value is -1, 0, or 1 as this
is numerically less than, equal to,
* or greater than rhs
.
* @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 BigDecimal
whose value is this/rhs
, using fixed point arithmetic.
*
* The same as {@link #divide(BigDecimal, int)}, where the BigDecimal
is rhs
, 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 BigDecimal
for the right hand side of the division.
* @return A plain BigDecimal
whose value is this/rhs
, using fixed point arithmetic.
* @throws ArithmeticException If rhs
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 BigDecimal
whose value is this/rhs
, using fixed point arithmetic and a
* rounding mode.
*
* The same as {@link #divide(BigDecimal, int, int)}, where the BigDecimal
is rhs
, and the
* second parameter is this.scale()
, and the third is round
.
*
* 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. *
*
* @param rhs The BigDecimal
for the right hand side of the division.
* @param round The int
rounding mode to be used for the division (see the {@link MathContext} class).
* @return A plain BigDecimal
whose value is this/rhs
, using fixed point arithmetic and
* the specified rounding mode.
* @throws IllegalArgumentException if round
is not a valid rounding mode.
* @throws ArithmeticException if rhs
is zero.
* @throws ArithmeticException if round
is {@link MathContext#ROUND_UNNECESSARY} and this.scale()
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 BigDecimal
whose value is this/rhs
, using fixed point arithmetic and a
* given scale and rounding mode.
*
* The same as {@link #divide(BigDecimal, MathContext)}, where the BigDecimal
is rhs
,
* new MathContext(0, MathContext.PLAIN, false, round)
, except that the length of the decimal part (the
* scale) to be used for the result is explicit rather than being taken from this
.
*
* 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 BigDecimal
for the right hand side of the division.
* @param scale The int
scale to be used for the result.
* @param round The int
rounding mode to be used for the division (see the {@link MathContext} class).
* @return A plain BigDecimal
whose value is this/rhs
, using fixed point arithmetic and
* the specified rounding mode.
* @throws IllegalArgumentException if round
is not a valid rounding mode.
* @throws ArithmeticException if rhs
is zero.
* @throws ArithmeticException if scale
is negative.
* @throws ArithmeticException if round
is {@link MathContext#ROUND_UNNECESSARY} and scale
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 BigDecimal
whose value is this/rhs
.
*
* Implements the division (/
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* @param rhs The BigDecimal
for the right hand side of the division.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is this/rhs
.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is the integer part of this/rhs
.
*
* The same as {@link #divideInteger(BigDecimal, MathContext)}, where the BigDecimal
is rhs
*
, and the context is new MathContext(0, MathContext.PLAIN)
.
*
* @param rhs The BigDecimal
for the right hand side of the integer division.
* @return A BigDecimal
whose value is the integer part of this/rhs
.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is the integer part of this/rhs
.
*
* Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class
* header}), and returns the result as a BigDecimal
object.
*
* @param rhs The BigDecimal
for the right hand side of the integer division.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is the integer part of this/rhs
.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is the maximum of this
and rhs
.
*
* The same as {@link #max(BigDecimal, MathContext)}, where the BigDecimal
is rhs
, and the
* context is new MathContext(0, MathContext.PLAIN)
.
*
* @param rhs The BigDecimal
for the right hand side of the comparison.
* @return A BigDecimal
whose value is the maximum of this
and rhs
.
* @stable ICU 2.0
*/
public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) {
return this.max(rhs, plainMC);
}
/**
* Returns a BigDecimal
whose value is the maximum of this
and rhs
.
*
* Returns the larger of the current object and the first parameter. *
* If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return 1
*
or 0
, then the result of calling the {@link #plus(MathContext)} method on the current object
* (using the same MathContext
parameter) is returned. Otherwise, the result of calling the
* {@link #plus(MathContext)} method on the first parameter object (using the same MathContext
* parameter) is returned.
*
* @param rhs The BigDecimal
for the right hand side of the comparison.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is the maximum of this
and rhs
.
* @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 BigDecimal
whose value is the minimum of this
and rhs
.
*
* The same as {@link #min(BigDecimal, MathContext)}, where the BigDecimal
is rhs
, and the
* context is new MathContext(0, MathContext.PLAIN)
.
*
* @param rhs The BigDecimal
for the right hand side of the comparison.
* @return A BigDecimal
whose value is the minimum of this
and rhs
.
* @stable ICU 2.0
*/
public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) {
return this.min(rhs, plainMC);
}
/**
* Returns a BigDecimal
whose value is the minimum of this
and rhs
.
*
* Returns the smaller of the current object and the first parameter. *
* If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return -1
*
or 0
, then the result of calling the {@link #plus(MathContext)} method on the current object
* (using the same MathContext
parameter) is returned. Otherwise, the result of calling the
* {@link #plus(MathContext)} method on the first parameter object (using the same MathContext
* parameter) is returned.
*
* @param rhs The BigDecimal
for the right hand side of the comparison.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is the minimum of this
and rhs
.
* @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 BigDecimal
whose value is this*rhs
, using fixed point arithmetic.
*
* The same as {@link #add(BigDecimal, MathContext)}, where the BigDecimal
is rhs
, and the
* context is new MathContext(0, MathContext.PLAIN)
.
*
* 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 BigDecimal
for the right hand side of the multiplication.
* @return A BigDecimal
whose value is this*rhs
, 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 BigDecimal
whose value is this*rhs
.
*
* Implements the multiplication (
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* @param rhs The BigDecimal
for the right hand side of the multiplication.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is this*rhs
.
* @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 BigDecimal
whose value is -this
.
*
* The same as {@link #negate(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN)
* .
*
* The length of the decimal part (the scale) of the result will be be this.scale()
*
*
* @return A BigDecimal
whose value is -this
.
* @stable ICU 2.0
*/
public com.ibm.icu.math.BigDecimal negate() {
return this.negate(plainMC);
}
/**
* Returns a BigDecimal
whose value is -this
.
*
* Implements the negation (Prefix -
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is -this
.
* @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 BigDecimal
whose value is +this
. Note that this
is not
* necessarily a plain BigDecimal
, but the result will always be.
*
* The same as {@link #plus(MathContext)}, where the context is new MathContext(0, MathContext.PLAIN)
.
*
* The length of the decimal part (the scale) of the result will be be this.scale()
*
* @return A BigDecimal
whose value is +this
.
* @stable ICU 2.0
*/
public com.ibm.icu.math.BigDecimal plus() {
return this.plus(plainMC);
}
/**
* Returns a BigDecimal
whose value is +this
.
*
* Implements the plus (Prefix +
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* This method is useful for rounding or otherwise applying a context to a decimal value.
*
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is +this
.
* @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 BigDecimal
whose value is this**rhs
, using fixed point arithmetic.
*
* The same as {@link #pow(BigDecimal, MathContext)}, where the BigDecimal
is rhs
, and the
* context is new MathContext(0, MathContext.PLAIN)
.
*
* The parameter is the power to which the this
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.
*
* In addition, the power must not be negative, as no MathContext
is used and so the result would then
* always be 0.
*
* @param rhs The BigDecimal
for the right hand side of the operation (the power).
* @return A BigDecimal
whose value is this**rhs
, using fixed point arithmetic.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is this**rhs
.
*
* Implements the power (
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* The first parameter is the power to which the this
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.
*
* If the digits
setting of the MathContext
parameter is 0, the power must be zero or
* positive.
*
* @param rhs The BigDecimal
for the right hand side of the operation (the power).
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is this**rhs
.
* @throws ArithmeticException if rhs
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 = -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 BigDecimal
whose value is the remainder of this/rhs
, using fixed point
* arithmetic.
*
* The same as {@link #remainder(BigDecimal, MathContext)}, where the BigDecimal
is rhs
,
* and the context is new MathContext(0, MathContext.PLAIN)
.
*
* This is not the modulo operator -- the result may be negative.
*
* @param rhs The BigDecimal
for the right hand side of the remainder operation.
* @return A BigDecimal
whose value is the remainder of this/rhs
, using fixed point
* arithmetic.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is the remainder of this/rhs
.
*
* Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}),
* and returns the result as a BigDecimal
object.
*
* This is not the modulo operator -- the result may be negative.
*
* @param rhs The BigDecimal
for the right hand side of the remainder operation.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is the remainder of this+rhs
.
* @throws ArithmeticException if rhs
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 BigDecimal
whose value is this-rhs
, using fixed point arithmetic.
*
* The same as {@link #subtract(BigDecimal, MathContext)}, where the BigDecimal
is rhs
,
* and the context is new MathContext(0, MathContext.PLAIN)
.
*
* 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 BigDecimal
for the right hand side of the subtraction.
* @return A BigDecimal
whose value is this-rhs
, 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 BigDecimal
whose value is this-rhs
.
*
* Implements the subtraction (-
) operator (as defined in the decimal documentation, see
* {@link BigDecimal class header}), and returns the result as a BigDecimal
object.
*
* @param rhs The BigDecimal
for the right hand side of the subtraction.
* @param set The MathContext
arithmetic settings.
* @return A BigDecimal
whose value is this-rhs
.
* @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 BigDecimal
to a byte
. If the BigDecimal
has a non-zero
* decimal part or is out of the possible range for a byte
(8-bit signed integer) result then an
* ArithmeticException
is thrown.
*
* @return A byte
equal in value to this
.
* @throws ArithmeticException if this
has a non-zero decimal part, or will not fit in a byte
.
* @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;
}
/**
* Converts this BigDecimal
to a double
. If the BigDecimal
is out of the
* possible range for a double
(64-bit signed floating point) result then an ArithmeticException
*
is thrown.
*
* The double produced is identical to result of expressing the BigDecimal
as a String
and
* then converting it using the Double(String)
constructor; this can result in values of
* Double.NEGATIVE_INFINITY
or Double.POSITIVE_INFINITY
.
*
* @return A double
corresponding to this
.
* @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 BigDecimal
with rhs
for equality.
*
* If the parameter is null
, or is not an instance of the BigDecimal type, or is not exactly equal to
* the current BigDecimal
object, then false is returned. Otherwise, true is returned.
*
* "Exactly equal", here, means that the String
representations of the BigDecimal
numbers
* are identical (they have the same characters in the same sequence).
*
* The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons.
*
* @param obj The Object
for the right hand side of the comparison.
* @return A boolean
whose value true if and only if the operands have identical string
* representations.
* @throws ClassCastException if rhs
cannot be cast to a BigDecimal
object.
* @stable ICU 2.0
* @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 BigDecimal
to a float
. If the BigDecimal
is out of the
* possible range for a float
(32-bit signed floating point) result then an ArithmeticException
*
is thrown.
*
* The float produced is identical to result of expressing the BigDecimal
as a String
and
* then converting it using the Float(String)
constructor; this can result in values of
* Float.NEGATIVE_INFINITY
or Float.POSITIVE_INFINITY
.
*
* @return A float
corresponding to this
.
* @stable ICU 2.0
*/
public float floatValue() {
return java.lang.Float.valueOf(this.toString()).floatValue();
}
/**
* Returns the String
representation of this BigDecimal
, modified by layout parameters.
*
* This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat
*
, 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.
*
*
* The parameters, for both forms of the format
method are all of type int
. A value of -1
* for any parameter indicates that the default action or value for that parameter should be used.
*
* The parameters, before
and after
, 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.
*
* before
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 before
is not large enough to
* contain the integer part of the number (including the sign, for negative numbers) an exception is thrown.
*
* after
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 after
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, MathContext.ROUND_HALF_UP
.
*
* 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 int
specifying the number of places before the decimal point. Use -1 for 'as many as are needed'.
* @param after The int
specifying the number of places after the decimal point. Use -1 for 'as many as are needed'.
* @return A String
representing this BigDecimal
, 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 String
representation of this BigDecimal
, modified by layout parameters and
* allowing exponential notation.
*
* This method is provided as a primitive for use by more sophisticated classes, such as DecimalFormat
*
, 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.
*
*
* The parameters are all of type int
. A value of -1 for any parameter indicates that the default
* action or value for that parameter should be used.
*
* The first two parameters (before
and after
) 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.
*
* The remaining parameters control the use of exponential notation and rounding. Three (explaces
,
* exdigits
, and exform
) 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.
*
* explaces
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 explaces
is -1) being to use as many
* as are needed. If explaces
is not -1, space is always reserved for an exponent; if one is not needed
* (for example, if the exponent will be 0) then explaces
+2 blanks are appended to the result. If explaces
*
is not -1 and is not large enough to contain the exponent, an exception is thrown.
*
* exdigits
sets the trigger point for use of exponential notation. If, before any rounding, the number
* of places needed before the decimal point exceeds exdigits
, or if the absolute value of the result
* is less than 0.000001
, then exponential form will be used, provided that exdigits
was
* specified. When exdigits
is -1, exponential notation will never be used. If 0 is specified for
* exdigits
, exponential notation is always used unless the exponent would be 0.
*
* exform
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 (before
* ). Otherwise, only one digit (plus sign, if negative) is needed.
*
* Finally, the sixth argument, exround
, 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 ROUND_
*
. The default (ROUND_HALF_UP
) may also be selected by using the value -1, as before.
*
* The special value MathContext.ROUND_UNNECESSARY
may be used to detect whether non-zero digits are
* discarded -- if exround
has this value than if non-zero digits would be discarded (rounded) during
* formatting then an ArithmeticException
is thrown.
*
* @param before The int
specifying the number of places before the decimal point. Use -1 for 'as many as
* are needed'.
* @param after The int
specifying the number of places after the decimal point. Use -1 for 'as many as
* are needed'.
* @param explaces The int
specifying the number of places to be used for any exponent. Use -1 for 'as many
* as are needed'.
* @param exdigits The int
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 int
specifying the form of exponential notation to be used (
* {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}).
* @param exround The int
specifying the rounding mode to use. Use -1 for the default,
* {@link MathContext#ROUND_HALF_UP}.
* @return A String
representing this BigDecimal
, 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 = -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 BigDecimal
. This hashcode is suitable for use by the
* java.util.Hashtable
class.
*
* Note that two
*
*
*
*
* 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
* If the given scale is less than the length of the decimal part (the scale) of this
* The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is
* 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
* If the given scale is less than the length of the decimal part (the scale) of this
* If
* This is an exact conversion; the result is the same as if the
* (Note: this method is provided only in the
* Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use
* {@link #toBigIntegerExact()}.
*
* @return The
* An exception is thrown if the decimal part (if any) is non-zero.
*
* @return The
* By definition, using the {@link #BigDecimal(String)} constructor on the result
* Returns a
* The number is constructed as though
* The result is given by:
*
*
* A 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). We must not alter the mantissa, here. '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. If OK, returns it as an
* int. This routine performs the calculation: 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;
}
/*
* This does NOT make a copy of the mantissa array.
* 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. BigDecimal
objects are only guaranteed to produce the same hashcode if they are
* exactly equal (that is, the String
representations of the BigDecimal
numbers are
* identical -- they have the same characters in the same sequence).
*
* @return An int
that is the hashcode for this
.
* @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 BigDecimal
to an int
. If the BigDecimal
has a non-zero
* decimal part it is discarded. If the BigDecimal
is out of the possible range for an int
* (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be
* decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact}
* method.
*
* @return An int
converted from this
, truncated and decapitated if necessary.
* @stable ICU 2.0
*/
public int intValue() {
return toBigInteger().intValue();
}
/**
* Converts this BigDecimal
to an int
. If the BigDecimal
has a non-zero
* decimal part or is out of the possible range for an int
(32-bit signed integer) result then an
* ArithmeticException
is thrown.
*
* @return An int
equal in value to this
.
* @throws ArithmeticException if this
has a non-zero decimal part, or will not fit in an int
.
* @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; // -1BigDecimal
to a long
. If the BigDecimal
has a non-zero
* decimal part it is discarded. If the BigDecimal
is out of the possible range for a long
* (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be
* decapitated.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact}
* method.
*
* @return A long
converted from this
, truncated and decapitated if necessary.
* @stable ICU 2.0
*/
public long longValue() {
return toBigInteger().longValue();
}
/**
* Converts this BigDecimal
to a long
. If the BigDecimal
has a non-zero
* decimal part or is out of the possible range for a long
(64-bit signed integer) result then an
* ArithmeticException
is thrown.
*
* @return A long
equal in value to this
.
* @throws ArithmeticException if this
has a non-zero decimal part, or will not fit in a long
.
* @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; // -1BigDecimal
whose decimal point has been moved to the left by a specified number of
* positions. The parameter, n
, specifies the number of positions to move the decimal point. That is,
* if n
is 0 or positive, the number returned is given by:
* this.multiply(TEN.pow(new BigDecimal(-n)))
* n
may be negative, in which case the method returns the same result as movePointRight(-n)
*
.
*
* @param n The int
specifying the number of places to move the decimal point leftwards.
* @return A BigDecimal
derived from this
, with the decimal point moved n
* 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 BigDecimal
whose decimal point has been moved to the right by a specified number of
* positions. The parameter, n
, specifies the number of positions to move the decimal point. That is,
* if n
is 0 or positive, the number returned is given by:
* this.multiply(TEN.pow(new BigDecimal(n)))
* n
may be negative, in which case the method returns the same result as movePointLeft(-n)
*
.
*
* @param n The int
specifying the number of places to move the decimal point rightwards.
* @return A BigDecimal
derived from this
, with the decimal point moved n
* 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 BigDecimal
. Returns a non-negative int
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 int
whose value is the scale of this BigDecimal
.
* @stable ICU 2.0
*/
public int scale() {
if (exp >= 0)
return 0; // scale can never be negative
return -exp;
}
/**
* Returns a plain BigDecimal
with a given scale.
* BigDecimal
then trailing zeros will be added to the decimal part as necessary.
* BigDecimal
then
* trailing digits will be removed, and in this case an ArithmeticException
is thrown if any discarded
* digits are non-zero.
*
* MathContext.ROUND_UNNECESSARY
.
*
* @param scale The int
specifying the scale of the resulting BigDecimal
.
* @return A plain BigDecimal
with the given scale.
* @throws ArithmeticException if scale
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 BigDecimal
with a given scale.
* BigDecimal
then trailing zeros will be added to the decimal part as necessary.
* BigDecimal
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 IllegalArgumentException
is thrown if
* round
is not a valid rounding mode.
* round
is MathContext.ROUND_UNNECESSARY
, an ArithmeticException
is
* thrown if any discarded digits are non-zero.
*
* @param scale The int
specifying the scale of the resulting BigDecimal
.
* @param round The int
rounding mode to be used for the division (see the {@link MathContext} class).
* @return A plain BigDecimal
with the given scale.
* @throws IllegalArgumentException if round
is not a valid rounding mode.
* @throws ArithmeticException if scale
is negative.
* @throws ArithmeticException if round
is MathContext.ROUND_UNNECESSARY
, 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 = -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 != -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 BigDecimal
to a short
. If the BigDecimal
has a non-zero
* decimal part or is out of the possible range for a short
(16-bit signed integer) result then an
* ArithmeticException
is thrown.
*
* @return A short
equal in value to this
.
* @throws ArithmeticException if this
has a non-zero decimal part, or will not fit in a short
.
* @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 BigDecimal
, as an int
. This returns the signum function
* value that represents the sign of this BigDecimal
. That is, -1 if the BigDecimal
is
* negative, 0 if it is numerically equal to zero, or 1 if it is positive.
*
* @return An int
which is -1 if the BigDecimal
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.]
}
/**
* Converts this BigDecimal
to a java.math.BigDecimal
.
* BigDecimal
were formatted as a plain
* number without any rounding or exponent and then the java.math.BigDecimal(java.lang.String)
* constructor were used to construct the result.
* com.ibm.icu.math
version of the BigDecimal class. It
* would not be present in a java.math
version.)
*
* @return The java.math.BigDecimal
equal in value to this BigDecimal
.
* @stable ICU 2.0
*/
public java.math.BigDecimal toBigDecimal() {
return new java.math.BigDecimal(this.unscaledValue(), this.scale());
}
/**
* Converts this BigDecimal
to a java.math.BigInteger
.
* java.math.BigInteger
equal in value to the integer part of this BigDecimal
.
* @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 (-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 BigDecimal
to a java.math.BigInteger
.
* java.math.BigInteger
equal in value to the integer part of this BigDecimal
.
* @throws ArithmeticException if this
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 BigDecimal
as a character array. The result of this method is the same as using the
* sequence toString().toCharArray()
, but avoids creating the intermediate String
and
* char[]
objects.
*
* @return The char[]
array corresponding to this BigDecimal
.
* @stable ICU 2.0
*/
public char[] toCharArray() {
return layout();
}
/**
* Returns the BigDecimal
as a String
. This returns a String
that exactly
* represents this BigDecimal
, as defined in the decimal documentation (see {@link BigDecimal class
* header}).
* String
will create a
* BigDecimal
that is exactly equal to the original BigDecimal
.
*
* @return The String
exactly corresponding to this BigDecimal
.
* @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 BigInteger
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 BigInteger
.
*
* @return The java.math.BigInteger
equal in value to this BigDecimal
multiplied by ten to
* the power of this.scale()
.
* @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 double
to a BigDecimal
.
* BigDecimal
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 NumberFormatException
is
* thrown.
* num
had been converted to a String
using the
* Double.toString()
method and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
* This is typically not an exact conversion.
*
* @param dub The double
to be translated.
* @return The BigDecimal
equal in value to dub
.
* @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 long
to a BigDecimal
. That is, returns a plain BigDecimal
* whose value is equal to the given long
.
*
* @param lint The long
to be translated.
* @return The BigDecimal
equal in value to lint
.
* @stable ICU 2.0
*/
public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
return valueOf(lint, 0);
}
/**
* Translates a long
to a BigDecimal
with a given scale. That is, returns a plain
* BigDecimal
whose unscaled value is equal to the given long
, adjusted by the second parameter,
* scale
.
* (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale)))
* NumberFormatException
is thrown if scale
is negative.
*
* @param lint The long
to be translated.
* @param scale The int
scale to be applied.
* @return The BigDecimal
equal in value to lint
.
* @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 = -scale; // exponent is -scale
return res;
}
/* ---------------------------------------------------------------- */
/* Private methods */
/* ---------------------------------------------------------------- */
/*
* C=A+(BM)
*
Where M is in the range -9 through +9