Methods Summary |
---|
public java.math.BigDecimal | abs()Returns a new {@code BigDecimal} whose value is the absolute value of
{@code this}. The scale of the result is the same as the scale of this.
return ((signum() < 0) ? negate() : this);
|
public java.math.BigDecimal | abs(java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is the absolute value of
{@code this}. The result is rounded according to the passed context
{@code mc}.
// BEGIN android-changed
BigDecimal result = abs();
result.inplaceRound(mc);
return result;
// END android-changed
|
public java.math.BigDecimal | add(java.math.BigDecimal augend)Returns a new {@code BigDecimal} whose value is {@code this + augend}.
The scale of the result is the maximum of the scales of the two
arguments.
int diffScale = this.scale - augend.scale;
// Fast return when some operand is zero
if (this.isZero()) {
if (diffScale <= 0) {
return augend;
}
if (augend.isZero()) {
return this;
}
} else if (augend.isZero()) {
if (diffScale >= 0) {
return this;
}
}
// Let be: this = [u1,s1] and augend = [u2,s2]
if (diffScale == 0) {
// case s1 == s2: [u1 + u2 , s1]
if (Math.max(this.bitLength, augend.bitLength) + 1 < 64) {
return valueOf(this.smallValue + augend.smallValue, this.scale);
}
return new BigDecimal(this.getUnscaledValue().add(augend.getUnscaledValue()), this.scale);
} else if (diffScale > 0) {
// case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1]
return addAndMult10(this, augend, diffScale);
} else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2]
return addAndMult10(augend, this, -diffScale);
}
|
public java.math.BigDecimal | add(java.math.BigDecimal augend, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this + augend}.
The result is rounded according to the passed context {@code mc}.
BigDecimal larger; // operand with the largest unscaled value
BigDecimal smaller; // operand with the smallest unscaled value
BigInteger tempBI;
long diffScale = (long)this.scale - augend.scale;
int largerSignum;
// Some operand is zero or the precision is infinity
if ((augend.isZero()) || (this.isZero())
|| (mc.getPrecision() == 0)) {
return add(augend).round(mc);
}
// Cases where there is room for optimizations
if (this.aproxPrecision() < diffScale - 1) {
larger = augend;
smaller = this;
} else if (augend.aproxPrecision() < -diffScale - 1) {
larger = this;
smaller = augend;
} else {// No optimization is done
return add(augend).round(mc);
}
if (mc.getPrecision() >= larger.aproxPrecision()) {
// No optimization is done
return add(augend).round(mc);
}
// Cases where it's unnecessary to add two numbers with very different scales
largerSignum = larger.signum();
if (largerSignum == smaller.signum()) {
tempBI = Multiplication.multiplyByPositiveInt(larger.getUnscaledValue(),10)
.add(BigInteger.valueOf(largerSignum));
} else {
tempBI = larger.getUnscaledValue().subtract(
BigInteger.valueOf(largerSignum));
tempBI = Multiplication.multiplyByPositiveInt(tempBI,10)
.add(BigInteger.valueOf(largerSignum * 9));
}
// Rounding the improved adding
larger = new BigDecimal(tempBI, larger.scale + 1);
return larger.round(mc);
|
private static java.math.BigDecimal | addAndMult10(java.math.BigDecimal thisValue, java.math.BigDecimal augend, int diffScale)
// BEGIN android-changed
if(diffScale < LONG_TEN_POW.length &&
Math.max(thisValue.bitLength,augend.bitLength+LONG_TEN_POW_BIT_LENGTH[diffScale])+1<64) {
return valueOf(thisValue.smallValue+augend.smallValue*LONG_TEN_POW[diffScale],thisValue.scale);
} else {
BigInt bi = Multiplication.multiplyByTenPow(augend.getUnscaledValue(),diffScale).bigInt;
bi.add(thisValue.getUnscaledValue().bigInt);
return new BigDecimal(new BigInteger(bi), thisValue.scale);
}
// END android-changed
|
private int | aproxPrecision()If the precision already was calculated it returns that value, otherwise
it calculates a very good approximation efficiently . Note that this
value will be {@code precision()} or {@code precision()-1}
in the worst case.
// BEGIN android-changed
return precision > 0
? precision
: (int) ((this.bitLength - 1) * LOG10_2) + 1;
// END android-changed
|
private static int | bitLength(long smallValue)
if(smallValue < 0) {
smallValue = ~smallValue;
}
return 64 - Long.numberOfLeadingZeros(smallValue);
|
private static int | bitLength(int smallValue)
if(smallValue < 0) {
smallValue = ~smallValue;
}
return 32 - Integer.numberOfLeadingZeros(smallValue);
|
public byte | byteValueExact()Returns this {@code BigDecimal} as a byte value if it has no fractional
part and if its value fits to the byte range ([-128..127]). If these
conditions are not met, an {@code ArithmeticException} is thrown.
return (byte)valueExact(8);
|
public int | compareTo(java.math.BigDecimal val)Compares this {@code BigDecimal} with {@code val}. Returns one of the
three values {@code 1}, {@code 0}, or {@code -1}. The method behaves as
if {@code this.subtract(val)} is computed. If this difference is > 0 then
1 is returned, if the difference is < 0 then -1 is returned, and if the
difference is 0 then 0 is returned. This means, that if two decimal
instances are compared which are equal in value but differ in scale, then
these two instances are considered as equal.
int thisSign = signum();
int valueSign = val.signum();
if( thisSign == valueSign) {
if(this.scale == val.scale && this.bitLength<64 && val.bitLength<64 ) {
return (smallValue < val.smallValue) ? -1 : (smallValue > val.smallValue) ? 1 : 0;
}
long diffScale = (long)this.scale - val.scale;
int diffPrecision = this.aproxPrecision() - val.aproxPrecision();
if (diffPrecision > diffScale + 1) {
return thisSign;
} else if (diffPrecision < diffScale - 1) {
return -thisSign;
} else {// thisSign == val.signum() and diffPrecision is aprox. diffScale
BigInteger thisUnscaled = this.getUnscaledValue();
BigInteger valUnscaled = val.getUnscaledValue();
// If any of both precision is bigger, append zeros to the shorter one
if (diffScale < 0) {
thisUnscaled = thisUnscaled.multiply(Multiplication.powerOf10(-diffScale));
} else if (diffScale > 0) {
valUnscaled = valUnscaled.multiply(Multiplication.powerOf10(diffScale));
}
return thisUnscaled.compareTo(valUnscaled);
}
} else if (thisSign < valueSign) {
return -1;
} else {
return 1;
}
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor, int scale, int roundingMode)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
As scale of the result the parameter {@code scale} is used. If rounding
is required to meet the specified scale, then the specified rounding mode
{@code roundingMode} is applied.
return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor, int scale, java.math.RoundingMode roundingMode)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
As scale of the result the parameter {@code scale} is used. If rounding
is required to meet the specified scale, then the specified rounding mode
{@code roundingMode} is applied.
// Let be: this = [u1,s1] and divisor = [u2,s2]
if (roundingMode == null) {
throw new NullPointerException();
}
if (divisor.isZero()) {
// math.04=Division by zero
throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
}
long diffScale = ((long)this.scale - divisor.scale) - scale;
if(this.bitLength < 64 && divisor.bitLength < 64 ) {
if(diffScale == 0) {
return dividePrimitiveLongs(this.smallValue,
divisor.smallValue,
scale,
roundingMode );
} else if(diffScale > 0) {
if(diffScale < LONG_TEN_POW.length &&
divisor.bitLength + LONG_TEN_POW_BIT_LENGTH[(int)diffScale] < 64) {
return dividePrimitiveLongs(this.smallValue,
divisor.smallValue*LONG_TEN_POW[(int)diffScale],
scale,
roundingMode);
}
} else { // diffScale < 0
if(-diffScale < LONG_TEN_POW.length &&
this.bitLength + LONG_TEN_POW_BIT_LENGTH[(int)-diffScale] < 64) {
return dividePrimitiveLongs(this.smallValue*LONG_TEN_POW[(int)-diffScale],
divisor.smallValue,
scale,
roundingMode);
}
}
}
BigInteger scaledDividend = this.getUnscaledValue();
BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2'
if (diffScale > 0) {
// Multiply 'u2' by: 10^((s1 - s2) - scale)
scaledDivisor = Multiplication.multiplyByTenPow(scaledDivisor, (int)diffScale);
} else if (diffScale < 0) {
// Multiply 'u1' by: 10^(scale - (s1 - s2))
scaledDividend = Multiplication.multiplyByTenPow(scaledDividend, (int)-diffScale);
}
return divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode);
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor, int roundingMode)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
The scale of the result is the scale of {@code this}. If rounding is
required to meet the specified scale, then the specified rounding mode
{@code roundingMode} is applied.
return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor, java.math.RoundingMode roundingMode)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
The scale of the result is the scale of {@code this}. If rounding is
required to meet the specified scale, then the specified rounding mode
{@code roundingMode} is applied.
return divide(divisor, scale, roundingMode);
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
The scale of the result is the difference of the scales of {@code this}
and {@code divisor}. If the exact result requires more digits, then the
scale is adjusted accordingly. For example, {@code 1/128 = 0.0078125}
which has a scale of {@code 7} and precision {@code 5}.
BigInteger p = this.getUnscaledValue();
BigInteger q = divisor.getUnscaledValue();
BigInteger gcd; // greatest common divisor between 'p' and 'q'
BigInteger quotAndRem[];
long diffScale = (long)scale - divisor.scale;
int newScale; // the new scale for final quotient
int k; // number of factors "2" in 'q'
int l = 0; // number of factors "5" in 'q'
int i = 1;
int lastPow = FIVE_POW.length - 1;
if (divisor.isZero()) {
// math.04=Division by zero
throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
}
if (p.signum() == 0) {
return zeroScaledBy(diffScale);
}
// To divide both by the GCD
gcd = p.gcd(q);
p = p.divide(gcd);
q = q.divide(gcd);
// To simplify all "2" factors of q, dividing by 2^k
k = q.getLowestSetBit();
q = q.shiftRight(k);
// To simplify all "5" factors of q, dividing by 5^l
do {
quotAndRem = q.divideAndRemainder(FIVE_POW[i]);
if (quotAndRem[1].signum() == 0) {
l += i;
if (i < lastPow) {
i++;
}
q = quotAndRem[0];
} else {
if (i == 1) {
break;
}
i = 1;
}
} while (true);
// If abs(q) != 1 then the quotient is periodic
if (!q.abs().equals(BigInteger.ONE)) {
// math.05=Non-terminating decimal expansion; no exact representable decimal result.
throw new ArithmeticException(Messages.getString("math.05")); //$NON-NLS-1$
}
// The sign of the is fixed and the quotient will be saved in 'p'
if (q.signum() < 0) {
p = p.negate();
}
// Checking if the new scale is out of range
newScale = toIntScale(diffScale + Math.max(k, l));
// k >= 0 and l >= 0 implies that k - l is in the 32-bit range
i = k - l;
p = (i > 0) ? Multiplication.multiplyByFivePow(p, i)
: p.shiftLeft(-i);
return new BigDecimal(p, newScale);
|
public java.math.BigDecimal | divide(java.math.BigDecimal divisor, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
The result is rounded according to the passed context {@code mc}. If the
passed math context specifies precision {@code 0}, then this call is
equivalent to {@code this.divide(divisor)}.
/* Calculating how many zeros must be append to 'dividend'
* to obtain a quotient with at least 'mc.precision()' digits */
long traillingZeros = mc.getPrecision() + 2L
+ divisor.aproxPrecision() - aproxPrecision();
long diffScale = (long)scale - divisor.scale;
long newScale = diffScale; // scale of the final quotient
int compRem; // to compare the remainder
int i = 1; // index
int lastPow = TEN_POW.length - 1; // last power of ten
BigInteger integerQuot; // for temporal results
BigInteger quotAndRem[] = {getUnscaledValue()};
// In special cases it reduces the problem to call the dual method
if ((mc.getPrecision() == 0) || (this.isZero())
|| (divisor.isZero())) {
return this.divide(divisor);
}
if (traillingZeros > 0) {
// To append trailing zeros at end of dividend
quotAndRem[0] = getUnscaledValue().multiply( Multiplication.powerOf10(traillingZeros) );
newScale += traillingZeros;
}
quotAndRem = quotAndRem[0].divideAndRemainder( divisor.getUnscaledValue() );
integerQuot = quotAndRem[0];
// Calculating the exact quotient with at least 'mc.precision()' digits
if (quotAndRem[1].signum() != 0) {
// Checking if: 2 * remainder >= divisor ?
compRem = quotAndRem[1].shiftLeft(1).compareTo( divisor.getUnscaledValue() );
// quot := quot * 10 + r; with 'r' in {-6,-5,-4, 0,+4,+5,+6}
integerQuot = integerQuot.multiply(BigInteger.TEN)
.add(BigInteger.valueOf(quotAndRem[0].signum() * (5 + compRem)));
newScale++;
} else {
// To strip trailing zeros until the preferred scale is reached
while (!integerQuot.testBit(0)) {
quotAndRem = integerQuot.divideAndRemainder(TEN_POW[i]);
if ((quotAndRem[1].signum() == 0)
&& (newScale - i >= diffScale)) {
newScale -= i;
if (i < lastPow) {
i++;
}
integerQuot = quotAndRem[0];
} else {
if (i == 1) {
break;
}
i = 1;
}
}
}
// To perform rounding
return new BigDecimal(integerQuot, toIntScale(newScale), mc);
|
public java.math.BigDecimal[] | divideAndRemainder(java.math.BigDecimal divisor)Returns a {@code BigDecimal} array which contains the integral part of
{@code this / divisor} at index 0 and the remainder {@code this %
divisor} at index 1. The quotient is rounded down towards zero to the
next integer.
BigDecimal quotAndRem[] = new BigDecimal[2];
quotAndRem[0] = this.divideToIntegralValue(divisor);
quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
return quotAndRem;
|
public java.math.BigDecimal[] | divideAndRemainder(java.math.BigDecimal divisor, java.math.MathContext mc)Returns a {@code BigDecimal} array which contains the integral part of
{@code this / divisor} at index 0 and the remainder {@code this %
divisor} at index 1. The quotient is rounded down towards zero to the
next integer. The rounding mode passed with the parameter {@code mc} is
not considered. But if the precision of {@code mc > 0} and the integral
part requires more digits, then an {@code ArithmeticException} is thrown.
BigDecimal quotAndRem[] = new BigDecimal[2];
quotAndRem[0] = this.divideToIntegralValue(divisor, mc);
quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
return quotAndRem;
|
private static java.math.BigDecimal | divideBigIntegers(java.math.BigInteger scaledDividend, java.math.BigInteger scaledDivisor, int scale, java.math.RoundingMode roundingMode)
BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor); // quotient and remainder
// If after division there is a remainder...
BigInteger quotient = quotAndRem[0];
BigInteger remainder = quotAndRem[1];
if (remainder.signum() == 0) {
return new BigDecimal(quotient, scale);
}
int sign = scaledDividend.signum() * scaledDivisor.signum();
int compRem; // 'compare to remainder'
if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after <<1
long rem = remainder.longValue();
long divisor = scaledDivisor.longValue();
compRem = longCompareTo(Math.abs(rem) << 1,Math.abs(divisor));
// To look if there is a carry
compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
sign * (5 + compRem), roundingMode);
} else {
// Checking if: remainder * 2 >= scaledDivisor
compRem = remainder.abs().shiftLeft(1).compareTo(scaledDivisor.abs());
compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
sign * (5 + compRem), roundingMode);
}
if (compRem != 0) {
if(quotient.bitLength() < 63) {
return valueOf(quotient.longValue() + compRem,scale);
}
quotient = quotient.add(BigInteger.valueOf(compRem));
return new BigDecimal(quotient, scale);
}
// Constructing the result with the appropriate unscaled value
return new BigDecimal(quotient, scale);
|
private static java.math.BigDecimal | dividePrimitiveLongs(long scaledDividend, long scaledDivisor, int scale, java.math.RoundingMode roundingMode)
long quotient = scaledDividend / scaledDivisor;
long remainder = scaledDividend % scaledDivisor;
int sign = Long.signum( scaledDividend ) * Long.signum( scaledDivisor );
if (remainder != 0) {
// Checking if: remainder * 2 >= scaledDivisor
int compRem; // 'compare to remainder'
compRem = longCompareTo(Math.abs(remainder) << 1,Math.abs(scaledDivisor));
// To look if there is a carry
quotient += roundingBehavior(((int)quotient) & 1,
sign * (5 + compRem),
roundingMode);
}
// Constructing the result with the appropriate unscaled value
return valueOf(quotient, scale);
|
public java.math.BigDecimal | divideToIntegralValue(java.math.BigDecimal divisor)Returns a new {@code BigDecimal} whose value is the integral part of
{@code this / divisor}. The quotient is rounded down towards zero to the
next integer. For example, {@code 0.5/0.2 = 2}.
BigInteger integralValue; // the integer of result
BigInteger powerOfTen; // some power of ten
BigInteger quotAndRem[] = {getUnscaledValue()};
long newScale = (long)this.scale - divisor.scale;
long tempScale = 0;
int i = 1;
int lastPow = TEN_POW.length - 1;
if (divisor.isZero()) {
// math.04=Division by zero
throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
}
if ((divisor.aproxPrecision() + newScale > this.aproxPrecision() + 1L)
|| (this.isZero())) {
/* If the divisor's integer part is greater than this's integer part,
* the result must be zero with the appropriate scale */
integralValue = BigInteger.ZERO;
} else if (newScale == 0) {
integralValue = getUnscaledValue().divide( divisor.getUnscaledValue() );
} else if (newScale > 0) {
powerOfTen = Multiplication.powerOf10(newScale);
integralValue = getUnscaledValue().divide( divisor.getUnscaledValue().multiply(powerOfTen) );
integralValue = integralValue.multiply(powerOfTen);
} else {// (newScale < 0)
powerOfTen = Multiplication.powerOf10(-newScale);
integralValue = getUnscaledValue().multiply(powerOfTen).divide( divisor.getUnscaledValue() );
// To strip trailing zeros approximating to the preferred scale
while (!integralValue.testBit(0)) {
quotAndRem = integralValue.divideAndRemainder(TEN_POW[i]);
if ((quotAndRem[1].signum() == 0)
&& (tempScale - i >= newScale)) {
tempScale -= i;
if (i < lastPow) {
i++;
}
integralValue = quotAndRem[0];
} else {
if (i == 1) {
break;
}
i = 1;
}
}
newScale = tempScale;
}
return ((integralValue.signum() == 0)
? zeroScaledBy(newScale)
: new BigDecimal(integralValue, toIntScale(newScale)));
|
public java.math.BigDecimal | divideToIntegralValue(java.math.BigDecimal divisor, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is the integral part of
{@code this / divisor}. The quotient is rounded down towards zero to the
next integer. The rounding mode passed with the parameter {@code mc} is
not considered. But if the precision of {@code mc > 0} and the integral
part requires more digits, then an {@code ArithmeticException} is thrown.
int mcPrecision = mc.getPrecision();
int diffPrecision = this.precision() - divisor.precision();
int lastPow = TEN_POW.length - 1;
long diffScale = (long)this.scale - divisor.scale;
long newScale = diffScale;
long quotPrecision = diffPrecision - diffScale + 1;
BigInteger quotAndRem[] = new BigInteger[2];
// In special cases it call the dual method
if ((mcPrecision == 0) || (this.isZero()) || (divisor.isZero())) {
return this.divideToIntegralValue(divisor);
}
// Let be: this = [u1,s1] and divisor = [u2,s2]
if (quotPrecision <= 0) {
quotAndRem[0] = BigInteger.ZERO;
} else if (diffScale == 0) {
// CASE s1 == s2: to calculate u1 / u2
quotAndRem[0] = this.getUnscaledValue().divide( divisor.getUnscaledValue() );
} else if (diffScale > 0) {
// CASE s1 >= s2: to calculate u1 / (u2 * 10^(s1-s2)
quotAndRem[0] = this.getUnscaledValue().divide(
divisor.getUnscaledValue().multiply(Multiplication.powerOf10(diffScale)) );
// To chose 10^newScale to get a quotient with at least 'mc.precision()' digits
newScale = Math.min(diffScale, Math.max(mcPrecision - quotPrecision + 1, 0));
// To calculate: (u1 / (u2 * 10^(s1-s2)) * 10^newScale
quotAndRem[0] = quotAndRem[0].multiply(Multiplication.powerOf10(newScale));
} else {// CASE s2 > s1:
/* To calculate the minimum power of ten, such that the quotient
* (u1 * 10^exp) / u2 has at least 'mc.precision()' digits. */
long exp = Math.min(-diffScale, Math.max((long)mcPrecision - diffPrecision, 0));
long compRemDiv;
// Let be: (u1 * 10^exp) / u2 = [q,r]
quotAndRem = this.getUnscaledValue().multiply(Multiplication.powerOf10(exp)).
divideAndRemainder(divisor.getUnscaledValue());
newScale += exp; // To fix the scale
exp = -newScale; // The remaining power of ten
// If after division there is a remainder...
if ((quotAndRem[1].signum() != 0) && (exp > 0)) {
// Log10(r) + ((s2 - s1) - exp) > mc.precision ?
compRemDiv = (new BigDecimal(quotAndRem[1])).precision()
+ exp - divisor.precision();
if (compRemDiv == 0) {
// To calculate: (r * 10^exp2) / u2
quotAndRem[1] = quotAndRem[1].multiply(Multiplication.powerOf10(exp)).
divide(divisor.getUnscaledValue());
compRemDiv = Math.abs(quotAndRem[1].signum());
}
if (compRemDiv > 0) {
// The quotient won't fit in 'mc.precision()' digits
// math.06=Division impossible
throw new ArithmeticException(Messages.getString("math.06")); //$NON-NLS-1$
}
}
}
// Fast return if the quotient is zero
if (quotAndRem[0].signum() == 0) {
return zeroScaledBy(diffScale);
}
BigInteger strippedBI = quotAndRem[0];
BigDecimal integralValue = new BigDecimal(quotAndRem[0]);
long resultPrecision = integralValue.precision();
int i = 1;
// To strip trailing zeros until the specified precision is reached
while (!strippedBI.testBit(0)) {
quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
if ((quotAndRem[1].signum() == 0) &&
((resultPrecision - i >= mcPrecision)
|| (newScale - i >= diffScale)) ) {
resultPrecision -= i;
newScale -= i;
if (i < lastPow) {
i++;
}
strippedBI = quotAndRem[0];
} else {
if (i == 1) {
break;
}
i = 1;
}
}
// To check if the result fit in 'mc.precision()' digits
if (resultPrecision > mcPrecision) {
// math.06=Division impossible
throw new ArithmeticException(Messages.getString("math.06")); //$NON-NLS-1$
}
integralValue.scale = toIntScale(newScale);
integralValue.setUnscaledValue(strippedBI);
return integralValue;
|
public double | doubleValue()Returns this {@code BigDecimal} as a double value. If {@code this} is too
big to be represented as an float, then {@code Double.POSITIVE_INFINITY}
or {@code Double.NEGATIVE_INFINITY} is returned.
Note, that if the unscaled value has more than 53 significant digits,
then this decimal cannot be represented exactly in a double variable. In
this case the result is rounded.
For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
represented exactly as a double, and thus {@code x1.equals(new
BigDecimal(x1.doubleValue())} returns {@code false} for this case.
Similarly, if the instance {@code new BigDecimal(9007199254740993L)} is
converted to a double, the result is {@code 9.007199254740992E15}.
int sign = signum();
int exponent = 1076; // bias + 53
int lowestSetBit;
int discardedSize;
long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
long bits; // IEEE-754 Standard
long tempBits; // for temporal calculations
BigInteger mantisa;
if ((powerOfTwo < -1074) || (sign == 0)) {
// Cases which 'this' is very small
return (sign * 0.0d);
} else if (powerOfTwo > 1025) {
// Cases which 'this' is very large
return (sign * Double.POSITIVE_INFINITY);
}
mantisa = getUnscaledValue().abs();
// Let be: this = [u,s], with s > 0
if (scale <= 0) {
// mantisa = abs(u) * 10^s
mantisa = mantisa.multiply(Multiplication.powerOf10(-scale));
} else {// (scale > 0)
BigInteger quotAndRem[];
BigInteger powerOfTen = Multiplication.powerOf10(scale);
int k = 100 - (int)powerOfTwo;
int compRem;
if (k > 0) {
/* Computing (mantisa * 2^k) , where 'k' is a enough big
* power of '2' to can divide by 10^s */
mantisa = mantisa.shiftLeft(k);
exponent -= k;
}
// Computing (mantisa * 2^k) / 10^s
quotAndRem = mantisa.divideAndRemainder(powerOfTen);
// To check if the fractional part >= 0.5
compRem = quotAndRem[1].shiftLeft(1).compareTo(powerOfTen);
// To add two rounded bits at end of mantisa
mantisa = quotAndRem[0].shiftLeft(2).add(
BigInteger.valueOf((compRem * (compRem + 3)) / 2 + 1));
exponent -= 2;
}
lowestSetBit = mantisa.getLowestSetBit();
discardedSize = mantisa.bitLength() - 54;
if (discardedSize > 0) {// (n > 54)
// mantisa = (abs(u) * 10^s) >> (n - 54)
bits = mantisa.shiftRight(discardedSize).longValue();
tempBits = bits;
// #bits = 54, to check if the discarded fraction produces a carry
if ((((bits & 1) == 1) && (lowestSetBit < discardedSize))
|| ((bits & 3) == 3)) {
bits += 2;
}
} else {// (n <= 54)
// mantisa = (abs(u) * 10^s) << (54 - n)
bits = mantisa.longValue() << -discardedSize;
tempBits = bits;
// #bits = 54, to check if the discarded fraction produces a carry:
if ((bits & 3) == 3) {
bits += 2;
}
}
// Testing bit 54 to check if the carry creates a new binary digit
if ((bits & 0x40000000000000L) == 0) {
// To drop the last bit of mantisa (first discarded)
bits >>= 1;
// exponent = 2^(s-n+53+bias)
exponent += discardedSize;
} else {// #bits = 54
bits >>= 2;
exponent += discardedSize + 1;
}
// To test if the 53-bits number fits in 'double'
if (exponent > 2046) {// (exponent - bias > 1023)
return (sign * Double.POSITIVE_INFINITY);
} else if (exponent <= 0) {// (exponent - bias <= -1023)
// Denormalized numbers (having exponent == 0)
if (exponent < -53) {// exponent - bias < -1076
return (sign * 0.0d);
}
// -1076 <= exponent - bias <= -1023
// To discard '- exponent + 1' bits
bits = tempBits >> 1;
tempBits = bits & (-1L >>> (63 + exponent));
bits >>= (-exponent );
// To test if after discard bits, a new carry is generated
if (((bits & 3) == 3) || (((bits & 1) == 1) && (tempBits != 0)
&& (lowestSetBit < discardedSize))) {
bits += 1;
}
exponent = 0;
bits >>= 1;
}
// Construct the 64 double bits: [sign(1), exponent(11), mantisa(52)]
bits = (sign & 0x8000000000000000L) | ((long)exponent << 52)
| (bits & 0xFFFFFFFFFFFFFL);
return Double.longBitsToDouble(bits);
|
public boolean | equals(java.lang.Object x)Returns {@code true} if {@code x} is a {@code BigDecimal} instance and if
this instance is equal to this big decimal. Two big decimals are equal if
their unscaled value and their scale is equal. For example, 1.0
(10*10^(-1)) is not equal to 1.00 (100*10^(-2)). Similarly, zero
instances are not equal if their scale differs.
if (this == x) {
return true;
}
if (x instanceof BigDecimal) {
BigDecimal x1 = (BigDecimal) x;
return x1.scale == scale
&& (bitLength < 64 ? (x1.smallValue == smallValue)
: intVal.equals(x1.intVal));
}
return false;
|
public float | floatValue()Returns this {@code BigDecimal} as a float value. If {@code this} is too
big to be represented as an float, then {@code Float.POSITIVE_INFINITY}
or {@code Float.NEGATIVE_INFINITY} is returned.
Note, that if the unscaled value has more than 24 significant digits,
then this decimal cannot be represented exactly in a float variable. In
this case the result is rounded.
For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
represented exactly as a float, and thus {@code x1.equals(new
BigDecimal(x1.folatValue())} returns {@code false} for this case.
Similarly, if the instance {@code new BigDecimal(16777217)} is converted
to a float, the result is {@code 1.6777216E}7.
/* A similar code like in doubleValue() could be repeated here,
* but this simple implementation is quite efficient. */
float floatResult = signum();
long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
if ((powerOfTwo < -149) || (floatResult == 0.0f)) {
// Cases which 'this' is very small
floatResult *= 0.0f;
} else if (powerOfTwo > 129) {
// Cases which 'this' is very large
floatResult *= Float.POSITIVE_INFINITY;
} else {
floatResult = (float)doubleValue();
}
return floatResult;
|
private java.math.BigInteger | getUnscaledValue()
if(intVal == null) {
intVal = BigInteger.valueOf(smallValue);
}
return intVal;
|
public int | hashCode()Returns a hash code for this {@code BigDecimal}.
if (hashCode != 0) {
return hashCode;
}
if (bitLength < 64) {
hashCode = (int)(smallValue & 0xffffffff);
hashCode = 33 * hashCode + (int)((smallValue >> 32) & 0xffffffff);
hashCode = 17 * hashCode + scale;
return hashCode;
}
hashCode = 17 * intVal.hashCode() + scale;
return hashCode;
|
private void | inplaceRound(java.math.MathContext mc)It does all rounding work of the public method
{@code round(MathContext)}, performing an inplace rounding
without creating a new object.
int mcPrecision = mc.getPrecision();
// BEGIN android-changed
if (aproxPrecision() < mcPrecision || mcPrecision == 0) {
return;
}
// END android-changed
int discardedPrecision = precision() - mcPrecision;
// If no rounding is necessary it returns immediately
if ((discardedPrecision <= 0)) {
return;
}
// When the number is small perform an efficient rounding
if (this.bitLength < 64) {
smallRound(mc, discardedPrecision);
return;
}
// Getting the integer part and the discarded fraction
BigInteger sizeOfFraction = Multiplication.powerOf10(discardedPrecision);
BigInteger[] integerAndFraction = getUnscaledValue().divideAndRemainder(sizeOfFraction);
long newScale = (long)scale - discardedPrecision;
int compRem;
BigDecimal tempBD;
// If the discarded fraction is non-zero, perform rounding
if (integerAndFraction[1].signum() != 0) {
// To check if the discarded fraction >= 0.5
compRem = (integerAndFraction[1].abs().shiftLeft(1).compareTo(sizeOfFraction));
// To look if there is a carry
compRem = roundingBehavior( integerAndFraction[0].testBit(0) ? 1 : 0,
integerAndFraction[1].signum() * (5 + compRem),
mc.getRoundingMode());
if (compRem != 0) {
integerAndFraction[0] = integerAndFraction[0].add(BigInteger.valueOf(compRem));
}
tempBD = new BigDecimal(integerAndFraction[0]);
// If after to add the increment the precision changed, we normalize the size
if (tempBD.precision() > mcPrecision) {
integerAndFraction[0] = integerAndFraction[0].divide(BigInteger.TEN);
newScale--;
}
}
// To update all internal fields
scale = toIntScale(newScale);
precision = mcPrecision;
setUnscaledValue(integerAndFraction[0]);
|
public int | intValue()Returns this {@code BigDecimal} as an int value. Any fractional part is
discarded. If the integral part of {@code this} is too big to be
represented as an int, then {@code this} % 2^32 is returned.
/*
* If scale <= -32 there are at least 32 trailing bits zero in
* 10^(-scale). If the scale is positive and very large the long value
* could be zero.
*/
return ((scale <= -32) || (scale > aproxPrecision())
? 0
: toBigInteger().intValue());
|
public int | intValueExact()Returns this {@code BigDecimal} as a int value if it has no fractional
part and if its value fits to the int range ([-2^{31}..2^{31}-1]). If
these conditions are not met, an {@code ArithmeticException} is thrown.
return (int)valueExact(32);
|
private boolean | isZero()
//Watch out: -1 has a bitLength=0
return bitLength == 0 && this.smallValue != -1;
|
private static int | longCompareTo(long value1, long value2)
return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0);
|
public long | longValue()Returns this {@code BigDecimal} as an long value. Any fractional part is
discarded. If the integral part of {@code this} is too big to be
represented as an long, then {@code this} % 2^64 is returned.
/*
* If scale <= -64 there are at least 64 trailing bits zero in
* 10^(-scale). If the scale is positive and very large the long value
* could be zero.
*/
return ((scale <= -64) || (scale > aproxPrecision()) ? 0L
: toBigInteger().longValue());
|
public long | longValueExact()Returns this {@code BigDecimal} as a long value if it has no fractional
part and if its value fits to the int range ([-2^{63}..2^{63}-1]). If
these conditions are not met, an {@code ArithmeticException} is thrown.
return valueExact(64);
|
public java.math.BigDecimal | max(java.math.BigDecimal val)Returns the maximum of this {@code BigDecimal} and {@code val}.
return ((compareTo(val) >= 0) ? this : val);
|
public java.math.BigDecimal | min(java.math.BigDecimal val)Returns the minimum of this {@code BigDecimal} and {@code val}.
return ((compareTo(val) <= 0) ? this : val);
|
private java.math.BigDecimal | movePoint(long newScale)
if (isZero()) {
return zeroScaledBy(Math.max(newScale, 0));
}
/*
* When: 'n'== Integer.MIN_VALUE isn't possible to call to
* movePointRight(-n) since -Integer.MIN_VALUE == Integer.MIN_VALUE
*/
if(newScale >= 0) {
if(bitLength < 64) {
return valueOf(smallValue,toIntScale(newScale));
}
return new BigDecimal(getUnscaledValue(), toIntScale(newScale));
}
if(-newScale < LONG_TEN_POW.length &&
bitLength + LONG_TEN_POW_BIT_LENGTH[(int)-newScale] < 64 ) {
return valueOf(smallValue*LONG_TEN_POW[(int)-newScale],0);
}
return new BigDecimal(Multiplication.multiplyByTenPow(getUnscaledValue(),(int)-newScale), 0);
|
public java.math.BigDecimal | movePointLeft(int n)Returns a new {@code BigDecimal} instance where the decimal point has
been moved {@code n} places to the left. If {@code n < 0} then the
decimal point is moved {@code -n} places to the right.
The result is obtained by changing its scale. If the scale of the result
becomes negative, then its precision is increased such that the scale is
zero.
Note, that {@code movePointLeft(0)} returns a result which is
mathematically equivalent, but which has {@code scale >= 0}.
return movePoint(scale + (long)n);
|
public java.math.BigDecimal | movePointRight(int n)Returns a new {@code BigDecimal} instance where the decimal point has
been moved {@code n} places to the right. If {@code n < 0} then the
decimal point is moved {@code -n} places to the left.
The result is obtained by changing its scale. If the scale of the result
becomes negative, then its precision is increased such that the scale is
zero.
Note, that {@code movePointRight(0)} returns a result which is
mathematically equivalent, but which has scale >= 0.
return movePoint(scale - (long)n);
|
public java.math.BigDecimal | multiply(java.math.BigDecimal multiplicand)Returns a new {@code BigDecimal} whose value is {@code this *
multiplicand}. The scale of the result is the sum of the scales of the
two arguments.
long newScale = (long)this.scale + multiplicand.scale;
if ((this.isZero()) || (multiplicand.isZero())) {
return zeroScaledBy(newScale);
}
/* Let be: this = [u1,s1] and multiplicand = [u2,s2] so:
* this x multiplicand = [ s1 * s2 , s1 + s2 ] */
if(this.bitLength + multiplicand.bitLength < 64) {
return valueOf(this.smallValue*multiplicand.smallValue,toIntScale(newScale));
}
return new BigDecimal(this.getUnscaledValue().multiply(
multiplicand.getUnscaledValue()), toIntScale(newScale));
|
public java.math.BigDecimal | multiply(java.math.BigDecimal multiplicand, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this *
multiplicand}. The result is rounded according to the passed context
{@code mc}.
BigDecimal result = multiply(multiplicand);
result.inplaceRound(mc);
return result;
|
public java.math.BigDecimal | negate()Returns a new {@code BigDecimal} whose value is the {@code -this}. The
scale of the result is the same as the scale of this.
if(bitLength < 63 || (bitLength == 63 && smallValue!=Long.MIN_VALUE)) {
return valueOf(-smallValue,scale);
}
return new BigDecimal(getUnscaledValue().negate(), scale);
|
public java.math.BigDecimal | negate(java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is the {@code -this}. The
result is rounded according to the passed context {@code mc}.
// BEGIN android-changed
BigDecimal result = negate();
result.inplaceRound(mc);
return result;
// END android-changed
|
public java.math.BigDecimal | plus()Returns a new {@code BigDecimal} whose value is {@code +this}. The scale
of the result is the same as the scale of this.
return this;
|
public java.math.BigDecimal | plus(java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code +this}. The result
is rounded according to the passed context {@code mc}.
return round(mc);
|
public java.math.BigDecimal | pow(int n)Returns a new {@code BigDecimal} whose value is {@code this ^ n}. The
scale of the result is {@code n} times the scales of {@code this}.
{@code x.pow(0)} returns {@code 1}, even if {@code x == 0}.
Implementation Note: The implementation is based on the ANSI standard
X3.274-1996 algorithm.
if (n == 0) {
return ONE;
}
if ((n < 0) || (n > 999999999)) {
// math.07=Invalid Operation
throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
}
long newScale = scale * (long)n;
// Let be: this = [u,s] so: this^n = [u^n, s*n]
return ((isZero())
? zeroScaledBy(newScale)
: new BigDecimal(getUnscaledValue().pow(n), toIntScale(newScale)));
|
public java.math.BigDecimal | pow(int n, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this ^ n}. The
result is rounded according to the passed context {@code mc}.
Implementation Note: The implementation is based on the ANSI standard
X3.274-1996 algorithm.
// The ANSI standard X3.274-1996 algorithm
int m = Math.abs(n);
int mcPrecision = mc.getPrecision();
int elength = (int)Math.log10(m) + 1; // decimal digits in 'n'
int oneBitMask; // mask of bits
BigDecimal accum; // the single accumulator
MathContext newPrecision = mc; // MathContext by default
// In particular cases, it reduces the problem to call the other 'pow()'
if ((n == 0) || ((isZero()) && (n > 0))) {
return pow(n);
}
if ((m > 999999999) || ((mcPrecision == 0) && (n < 0))
|| ((mcPrecision > 0) && (elength > mcPrecision))) {
// math.07=Invalid Operation
throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
}
if (mcPrecision > 0) {
newPrecision = new MathContext( mcPrecision + elength + 1,
mc.getRoundingMode());
}
// The result is calculated as if 'n' were positive
accum = round(newPrecision);
oneBitMask = Integer.highestOneBit(m) >> 1;
while (oneBitMask > 0) {
accum = accum.multiply(accum, newPrecision);
if ((m & oneBitMask) == oneBitMask) {
accum = accum.multiply(this, newPrecision);
}
oneBitMask >>= 1;
}
// If 'n' is negative, the value is divided into 'ONE'
if (n < 0) {
accum = ONE.divide(accum, newPrecision);
}
// The final value is rounded to the destination precision
accum.inplaceRound(mc);
return accum;
|
public int | precision()Returns the precision of this {@code BigDecimal}. The precision is the
number of decimal digits used to represent this decimal. It is equivalent
to the number of digits of the unscaled value. The precision of {@code 0}
is {@code 1} (independent of the scale).
// Checking if the precision already was calculated
if (precision > 0) {
return precision;
}
int bitLength = this.bitLength;
int decimalDigits = 1; // the precision to be calculated
double doubleUnsc = 1; // intVal in 'double'
if (bitLength < 1024) {
// To calculate the precision for small numbers
if (bitLength >= 64) {
doubleUnsc = getUnscaledValue().doubleValue();
} else if (bitLength >= 1) {
doubleUnsc = smallValue;
}
decimalDigits += Math.log10(Math.abs(doubleUnsc));
} else {// (bitLength >= 1024)
/* To calculate the precision for large numbers
* Note that: 2 ^(bitlength() - 1) <= intVal < 10 ^(precision()) */
decimalDigits += (bitLength - 1) * LOG10_2;
// If after division the number isn't zero, exists an aditional digit
if (getUnscaledValue().divide(Multiplication.powerOf10(decimalDigits)).signum() != 0) {
decimalDigits++;
}
}
precision = decimalDigits;
return precision;
|
private void | readObject(java.io.ObjectInputStream in)Assignes all transient fields upon deserialization of a
{@code BigDecimal} instance (bitLength and smallValue). The transient
field precision is assigned lazily.
in.defaultReadObject();
this.bitLength = intVal.bitLength();
if (this.bitLength < 64) {
this.smallValue = intVal.longValue();
}
|
public java.math.BigDecimal | remainder(java.math.BigDecimal divisor)Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
The remainder is defined as {@code this -
this.divideToIntegralValue(divisor) * divisor}.
return divideAndRemainder(divisor)[1];
|
public java.math.BigDecimal | remainder(java.math.BigDecimal divisor, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
The remainder is defined as {@code this -
this.divideToIntegralValue(divisor) * divisor}.
The specified rounding mode {@code mc} is used for the division only.
return divideAndRemainder(divisor, mc)[1];
|
public java.math.BigDecimal | round(java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this}, rounded
according to the passed context {@code mc}.
If {@code mc.precision = 0}, then no rounding is performed.
If {@code mc.precision > 0} and {@code mc.roundingMode == UNNECESSARY},
then an {@code ArithmeticException} is thrown if the result cannot be
represented exactly within the given precision.
BigDecimal thisBD = new BigDecimal(getUnscaledValue(), scale);
thisBD.inplaceRound(mc);
return thisBD;
|
private static int | roundingBehavior(int parityBit, int fraction, java.math.RoundingMode roundingMode)Return an increment that can be -1,0 or 1, depending of
{@code roundingMode}.
int increment = 0; // the carry after rounding
switch (roundingMode) {
case UNNECESSARY:
if (fraction != 0) {
// math.08=Rounding necessary
throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
}
break;
case UP:
increment = Integer.signum(fraction);
break;
case DOWN:
break;
case CEILING:
increment = Math.max(Integer.signum(fraction), 0);
break;
case FLOOR:
increment = Math.min(Integer.signum(fraction), 0);
break;
case HALF_UP:
if (Math.abs(fraction) >= 5) {
increment = Integer.signum(fraction);
}
break;
case HALF_DOWN:
if (Math.abs(fraction) > 5) {
increment = Integer.signum(fraction);
}
break;
case HALF_EVEN:
if (Math.abs(fraction) + parityBit > 5) {
increment = Integer.signum(fraction);
}
break;
}
return increment;
|
public int | scale()Returns the scale of this {@code BigDecimal}. The scale is the number of
digits behind the decimal point. The value of this {@code BigDecimal} is
the unsignedValue * 10^(-scale). If the scale is negative, then this
{@code BigDecimal} represents a big integer.
return scale;
|
public java.math.BigDecimal | scaleByPowerOfTen(int n)Returns a new {@code BigDecimal} whose value is {@code this} 10^{@code n}.
The scale of the result is {@code this.scale()} - {@code n}.
The precision of the result is the precision of {@code this}.
This method has the same effect as {@link #movePointRight}, except that
the precision is not changed.
long newScale = scale - (long)n;
if(bitLength < 64) {
//Taking care when a 0 is to be scaled
if( smallValue==0 ){
return zeroScaledBy( newScale );
}
return valueOf(smallValue,toIntScale(newScale));
}
return new BigDecimal(getUnscaledValue(), toIntScale(newScale));
|
public java.math.BigDecimal | setScale(int newScale, java.math.RoundingMode roundingMode)Returns a new {@code BigDecimal} instance with the specified scale.
If the new scale is greater than the old scale, then additional zeros are
added to the unscaled value. In this case no rounding is necessary.
If the new scale is smaller than the old scale, then trailing digits are
removed. If these trailing digits are not zero, then the remaining
unscaled value has to be rounded. For this rounding operation the
specified rounding mode is used.
if (roundingMode == null) {
throw new NullPointerException();
}
long diffScale = newScale - (long)scale;
// Let be: 'this' = [u,s]
if(diffScale == 0) {
return this;
}
if(diffScale > 0) {
// return [u * 10^(s2 - s), newScale]
if(diffScale < LONG_TEN_POW.length &&
(this.bitLength + LONG_TEN_POW_BIT_LENGTH[(int)diffScale]) < 64 ) {
return valueOf(this.smallValue*LONG_TEN_POW[(int)diffScale],newScale);
}
return new BigDecimal(Multiplication.multiplyByTenPow(getUnscaledValue(),(int)diffScale), newScale);
}
// diffScale < 0
// return [u,s] / [1,newScale] with the appropriate scale and rounding
if(this.bitLength < 64 && -diffScale < LONG_TEN_POW.length) {
return dividePrimitiveLongs(this.smallValue, LONG_TEN_POW[(int)-diffScale], newScale,roundingMode);
}
return divideBigIntegers(this.getUnscaledValue(),Multiplication.powerOf10(-diffScale),newScale,roundingMode);
|
public java.math.BigDecimal | setScale(int newScale, int roundingMode)Returns a new {@code BigDecimal} instance with the specified scale.
If the new scale is greater than the old scale, then additional zeros are
added to the unscaled value. In this case no rounding is necessary.
If the new scale is smaller than the old scale, then trailing digits are
removed. If these trailing digits are not zero, then the remaining
unscaled value has to be rounded. For this rounding operation the
specified rounding mode is used.
return setScale(newScale, RoundingMode.valueOf(roundingMode));
|
public java.math.BigDecimal | setScale(int newScale)Returns a new {@code BigDecimal} instance with the specified scale. If
the new scale is greater than the old scale, then additional zeros are
added to the unscaled value. If the new scale is smaller than the old
scale, then trailing zeros are removed. If the trailing digits are not
zeros then an ArithmeticException is thrown.
If no exception is thrown, then the following equation holds: {@code
x.setScale(s).compareTo(x) == 0}.
return setScale(newScale, RoundingMode.UNNECESSARY);
|
private void | setUnscaledValue(java.math.BigInteger unscaledValue)
this.intVal = unscaledValue;
this.bitLength = unscaledValue.bitLength();
if(this.bitLength < 64) {
this.smallValue = unscaledValue.longValue();
}
|
public short | shortValueExact()Returns this {@code BigDecimal} as a short value if it has no fractional
part and if its value fits to the short range ([-2^{15}..2^{15}-1]). If
these conditions are not met, an {@code ArithmeticException} is thrown.
return (short)valueExact(16);
|
public int | signum()Returns the sign of this {@code BigDecimal}.
if( bitLength < 64) {
return Long.signum( this.smallValue );
}
return getUnscaledValue().signum();
|
private void | smallRound(java.math.MathContext mc, int discardedPrecision)This method implements an efficient rounding for numbers which unscaled
value fits in the type {@code long}.
long sizeOfFraction = LONG_TEN_POW[discardedPrecision];
long newScale = (long)scale - discardedPrecision;
long unscaledVal = smallValue;
// Getting the integer part and the discarded fraction
long integer = unscaledVal / sizeOfFraction;
long fraction = unscaledVal % sizeOfFraction;
int compRem;
// If the discarded fraction is non-zero perform rounding
if (fraction != 0) {
// To check if the discarded fraction >= 0.5
compRem = longCompareTo(Math.abs(fraction) << 1,sizeOfFraction);
// To look if there is a carry
integer += roundingBehavior( ((int)integer) & 1,
Long.signum(fraction) * (5 + compRem),
mc.getRoundingMode());
// If after to add the increment the precision changed, we normalize the size
if (Math.log10(Math.abs(integer)) >= mc.getPrecision()) {
integer /= 10;
newScale--;
}
}
// To update all internal fields
scale = toIntScale(newScale);
precision = mc.getPrecision();
smallValue = integer;
bitLength = bitLength(integer);
intVal = null;
|
public java.math.BigDecimal | stripTrailingZeros()Returns a new {@code BigDecimal} instance with the same value as {@code
this} but with a unscaled value where the trailing zeros have been
removed. If the unscaled value of {@code this} has n trailing zeros, then
the scale and the precision of the result has been reduced by n.
int i = 1; // 1 <= i <= 18
int lastPow = TEN_POW.length - 1;
long newScale = scale;
if (isZero()) {
// BEGIN android-changed
return new BigDecimal("0");
// END android-changed
}
BigInteger strippedBI = getUnscaledValue();
BigInteger[] quotAndRem;
// while the number is even...
while (!strippedBI.testBit(0)) {
// To divide by 10^i
quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
// To look the remainder
if (quotAndRem[1].signum() == 0) {
// To adjust the scale
newScale -= i;
if (i < lastPow) {
// To set to the next power
i++;
}
strippedBI = quotAndRem[0];
} else {
if (i == 1) {
// 'this' has no more trailing zeros
break;
}
// To set to the smallest power of ten
i = 1;
}
}
return new BigDecimal(strippedBI, toIntScale(newScale));
|
public java.math.BigDecimal | subtract(java.math.BigDecimal subtrahend)Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}
. The scale of the result is the maximum of the scales of the two
arguments.
int diffScale = this.scale - subtrahend.scale;
// Fast return when some operand is zero
if (this.isZero()) {
if (diffScale <= 0) {
return subtrahend.negate();
}
if (subtrahend.isZero()) {
return this;
}
} else if (subtrahend.isZero()) {
if (diffScale >= 0) {
return this;
}
}
// Let be: this = [u1,s1] and subtrahend = [u2,s2] so:
if (diffScale == 0) {
// case s1 = s2 : [u1 - u2 , s1]
if (Math.max(this.bitLength, subtrahend.bitLength) + 1 < 64) {
return valueOf(this.smallValue - subtrahend.smallValue,this.scale);
}
return new BigDecimal(this.getUnscaledValue().subtract(subtrahend.getUnscaledValue()), this.scale);
} else if (diffScale > 0) {
// case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ]
if(diffScale < LONG_TEN_POW.length &&
Math.max(this.bitLength,subtrahend.bitLength+LONG_TEN_POW_BIT_LENGTH[diffScale])+1<64) {
return valueOf(this.smallValue-subtrahend.smallValue*LONG_TEN_POW[diffScale],this.scale);
}
return new BigDecimal(this.getUnscaledValue().subtract(
Multiplication.multiplyByTenPow(subtrahend.getUnscaledValue(),diffScale)), this.scale);
} else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ]
diffScale = -diffScale;
if(diffScale < LONG_TEN_POW.length &&
Math.max(this.bitLength+LONG_TEN_POW_BIT_LENGTH[diffScale],subtrahend.bitLength)+1<64) {
return valueOf(this.smallValue*LONG_TEN_POW[diffScale]-subtrahend.smallValue,subtrahend.scale);
}
return new BigDecimal(Multiplication.multiplyByTenPow(this.getUnscaledValue(),diffScale)
.subtract(subtrahend.getUnscaledValue()), subtrahend.scale);
}
|
public java.math.BigDecimal | subtract(java.math.BigDecimal subtrahend, java.math.MathContext mc)Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
The result is rounded according to the passed context {@code mc}.
long diffScale = subtrahend.scale - (long)this.scale;
int thisSignum;
BigDecimal leftOperand; // it will be only the left operand (this)
BigInteger tempBI;
// Some operand is zero or the precision is infinity
if ((subtrahend.isZero()) || (this.isZero())
|| (mc.getPrecision() == 0)) {
return subtract(subtrahend).round(mc);
}
// Now: this != 0 and subtrahend != 0
if (subtrahend.aproxPrecision() < diffScale - 1) {
// Cases where it is unnecessary to subtract two numbers with very different scales
if (mc.getPrecision() < this.aproxPrecision()) {
thisSignum = this.signum();
if (thisSignum != subtrahend.signum()) {
tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10)
.add(BigInteger.valueOf(thisSignum));
} else {
tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum));
tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10)
.add(BigInteger.valueOf(thisSignum * 9));
}
// Rounding the improved subtracting
leftOperand = new BigDecimal(tempBI, this.scale + 1);
return leftOperand.round(mc);
}
}
// No optimization is done
return subtract(subtrahend).round(mc);
|
public java.math.BigInteger | toBigInteger()Returns this {@code BigDecimal} as a big integer instance. A fractional
part is discarded.
if ((scale == 0) || (isZero())) {
return getUnscaledValue();
} else if (scale < 0) {
return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
} else {// (scale > 0)
return getUnscaledValue().divide(Multiplication.powerOf10(scale));
}
|
public java.math.BigInteger | toBigIntegerExact()Returns this {@code BigDecimal} as a big integer instance if it has no
fractional part. If this {@code BigDecimal} has a fractional part, i.e.
if rounding would be necessary, an {@code ArithmeticException} is thrown.
if ((scale == 0) || (isZero())) {
return getUnscaledValue();
} else if (scale < 0) {
return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
} else {// (scale > 0)
BigInteger[] integerAndFraction;
// An optimization before do a heavy division
if ((scale > aproxPrecision()) || (scale > getUnscaledValue().getLowestSetBit())) {
// math.08=Rounding necessary
throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
}
integerAndFraction = getUnscaledValue().divideAndRemainder(Multiplication.powerOf10(scale));
if (integerAndFraction[1].signum() != 0) {
// It exists a non-zero fractional part
// math.08=Rounding necessary
throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
}
return integerAndFraction[0];
}
|
public java.lang.String | toEngineeringString()Returns a string representation of this {@code BigDecimal}. This
representation always prints all significant digits of this value.
If the scale is negative or if {@code scale - precision >= 6} then
engineering notation is used. Engineering notation is similar to the
scientific notation except that the exponent is made to be a multiple of
3 such that the integer part is >= 1 and < 1000.
String intString = getUnscaledValue().toString();
if (scale == 0) {
return intString;
}
int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
int end = intString.length();
long exponent = -(long)scale + end - begin;
StringBuffer result = new StringBuffer(intString);
if ((scale > 0) && (exponent >= -6)) {
if (exponent >= 0) {
result.insert(end - scale, '.");
} else {
result.insert(begin - 1, "0."); //$NON-NLS-1$
result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
}
} else {
int delta = end - begin;
int rem = (int)(exponent % 3);
if (rem != 0) {
// adjust exponent so it is a multiple of three
if (getUnscaledValue().signum() == 0) {
// zero value
rem = (rem < 0) ? -rem : 3 - rem;
exponent += rem;
} else {
// nonzero value
rem = (rem < 0) ? rem + 3 : rem;
exponent -= rem;
begin += rem;
}
if (delta < 3) {
for (int i = rem - delta; i > 0; i--) {
result.insert(end++, '0");
}
}
}
if (end - begin >= 1) {
result.insert(begin, '.");
end++;
}
if (exponent != 0) {
result.insert(end, 'E");
if (exponent > 0) {
result.insert(++end, '+");
}
result.insert(++end, Long.toString(exponent));
}
}
return result.toString();
|
private static int | toIntScale(long longScale)It tests if a scale of type {@code long} fits in 32 bits. It
returns the same scale being casted to {@code int} type when is
possible, otherwise throws an exception.
if (longScale < Integer.MIN_VALUE) {
// math.09=Overflow
throw new ArithmeticException(Messages.getString("math.09")); //$NON-NLS-1$
} else if (longScale > Integer.MAX_VALUE) {
// math.0A=Underflow
throw new ArithmeticException(Messages.getString("math.0A")); //$NON-NLS-1$
} else {
return (int)longScale;
}
|
public java.lang.String | toPlainString()Returns a string representation of this {@code BigDecimal}. No scientific
notation is used. This methods adds zeros where necessary.
If this string representation is used to create a new instance, this
instance is generally not identical to {@code this} as the precision
changes.
{@code x.equals(new BigDecimal(x.toPlainString())} usually returns
{@code false}.
{@code x.compareTo(new BigDecimal(x.toPlainString())} returns {@code 0}.
String intStr = getUnscaledValue().toString();
if ((scale == 0) || ((isZero()) && (scale < 0))) {
return intStr;
}
int begin = (signum() < 0) ? 1 : 0;
int delta = scale;
// We take space for all digits, plus a possible decimal point, plus 'scale'
StringBuffer result = new StringBuffer(intStr.length() + 1 + Math.abs(scale));
if (begin == 1) {
// If the number is negative, we insert a '-' character at front
result.append('-");
}
if (scale > 0) {
delta -= (intStr.length() - begin);
if (delta >= 0) {
result.append("0."); //$NON-NLS-1$
// To append zeros after the decimal point
for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) {
result.append(CH_ZEROS);
}
result.append(CH_ZEROS, 0, delta);
result.append(intStr.substring(begin));
} else {
delta = begin - delta;
result.append(intStr.substring(begin, delta));
result.append('.");
result.append(intStr.substring(delta));
}
} else {// (scale <= 0)
result.append(intStr.substring(begin));
// To append trailing zeros
for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) {
result.append(CH_ZEROS);
}
result.append(CH_ZEROS, 0, -delta);
}
return result.toString();
|
public java.lang.String | toString()Returns a canonical string representation of this {@code BigDecimal}. If
necessary, scientific notation is used. This representation always prints
all significant digits of this value.
If the scale is negative or if {@code scale - precision >= 6} then
scientific notation is used.
if (toStringImage != null) {
return toStringImage;
}
if(bitLength < 32) {
toStringImage = Conversion.toDecimalScaledString(smallValue,scale);
return toStringImage;
}
String intString = getUnscaledValue().toString();
if (scale == 0) {
return intString;
}
int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
int end = intString.length();
long exponent = -(long)scale + end - begin;
StringBuffer result = new StringBuffer();
result.append(intString);
if ((scale > 0) && (exponent >= -6)) {
if (exponent >= 0) {
result.insert(end - scale, '.");
} else {
result.insert(begin - 1, "0."); //$NON-NLS-1$
result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
}
} else {
if (end - begin >= 1) {
result.insert(begin, '.");
end++;
}
result.insert(end, 'E");
if (exponent > 0) {
result.insert(++end, '+");
}
result.insert(++end, Long.toString(exponent));
}
toStringImage = result.toString();
return toStringImage;
|
public java.math.BigDecimal | ulp()Returns the unit in the last place (ULP) of this {@code BigDecimal}
instance. An ULP is the distance to the nearest big decimal with the same
precision.
The amount of a rounding error in the evaluation of a floating-point
operation is often expressed in ULPs. An error of 1 ULP is often seen as
a tolerable error.
For class {@code BigDecimal}, the ULP of a number is simply 10^(-scale).
For example, {@code new BigDecimal(0.1).ulp()} returns {@code 1E-55}.
return valueOf(1, scale);
|
public java.math.BigInteger | unscaledValue()Returns the unscaled value (mantissa) of this {@code BigDecimal} instance
as a {@code BigInteger}. The unscaled value can be computed as {@code
this} 10^(scale).
return getUnscaledValue();
|
private long | valueExact(int bitLengthOfType)If {@code intVal} has a fractional part throws an exception,
otherwise it counts the number of bits of value and checks if it's out of
the range of the primitive type. If the number fits in the primitive type
returns this number as {@code long}, otherwise throws an
exception.
BigInteger bigInteger = toBigIntegerExact();
if (bigInteger.bitLength() < bitLengthOfType) {
// It fits in the primitive type
return bigInteger.longValue();
}
// math.08=Rounding necessary
throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
|
public static java.math.BigDecimal | valueOf(long unscaledVal, int scale)Returns a new {@code BigDecimal} instance whose value is equal to {@code
unscaledVal} 10^(-{@code scale}). The scale of the result is {@code
scale}, and its unscaled value is {@code unscaledVal}.
if (scale == 0) {
return valueOf(unscaledVal);
}
if ((unscaledVal == 0) && (scale >= 0)
&& (scale < ZERO_SCALED_BY.length)) {
return ZERO_SCALED_BY[scale];
}
return new BigDecimal(unscaledVal, scale);
|
public static java.math.BigDecimal | valueOf(long unscaledVal)Returns a new {@code BigDecimal} instance whose value is equal to {@code
unscaledVal}. The scale of the result is {@code 0}, and its unscaled
value is {@code unscaledVal}.
if ((unscaledVal >= 0) && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) {
return BI_SCALED_BY_ZERO[(int)unscaledVal];
}
return new BigDecimal(unscaledVal,0);
|
public static java.math.BigDecimal | valueOf(double val)Returns a new {@code BigDecimal} instance whose value is equal to {@code
unscaledVal}. The new decimal is constructed as if the {@code
BigDecimal(String)} constructor is called with an argument which is equal
to {@code Double.toString(val)}. For example, {@code valueOf(0.1)} is
converted to (unscaled=1, scale=1), although the double {@code 0.1}
cannot be represented exactly as a double value. In contrast to that, a
new {@code BigDecimal(0.1)} instance has the value {@code
0.1000000000000000055511151231257827021181583404541015625} with an
unscaled value {@code
1000000000000000055511151231257827021181583404541015625} and the scale
{@code 55}.
if (Double.isInfinite(val) || Double.isNaN(val)) {
// math.03=Infinity or NaN
throw new NumberFormatException(Messages.getString("math.03")); //$NON-NLS-1$
}
return new BigDecimal(Double.toString(val));
|
private void | writeObject(java.io.ObjectOutputStream out)Prepares this {@code BigDecimal} for serialization, i.e. the
non-transient field {@code intVal} is assigned.
getUnscaledValue();
out.defaultWriteObject();
|
private static java.math.BigDecimal | zeroScaledBy(long longScale)It returns the value 0 with the most approximated scale of type
{@code int}. if {@code longScale > Integer.MAX_VALUE} the
scale will be {@code Integer.MAX_VALUE}; if
{@code longScale < Integer.MIN_VALUE} the scale will be
{@code Integer.MIN_VALUE}; otherwise {@code longScale} is
casted to the type {@code int}.
if (longScale == (int) longScale) {
return valueOf(0,(int)longScale);
}
if (longScale >= 0) {
return new BigDecimal( 0, Integer.MAX_VALUE);
}
return new BigDecimal( 0, Integer.MIN_VALUE);
|