JDK中BigDecimal的代码实现
package java.math;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.io.StreamCorruptedException;
import java.util.Arrays;
public class BigDecimal extends Number
implements Comparable<BigDecimal>
{
private volatile BigInteger intVal;
private int scale;
private transient int precision;
private transient String stringCache;
static final long INFLATED = -9223372036854775808L;
private transient long intCompact;
private static final int MAX_COMPACT_DIGITS = 18;
private static final int MAX_BIGINT_BITS = 62;
private static final long serialVersionUID = 6108874887143696463L;
private static final ThreadLocal<StringBuilderHelper> threadLocalStringBuilderHelper;
private static final BigDecimal[] zeroThroughTen;
private static final BigDecimal[] ZERO_SCALED_BY;
private static final long HALF_LONG_MAX_VALUE = 4611686018427387903L;
private static final long HALF_LONG_MIN_VALUE = -4611686018427387904L;
public static final BigDecimal ZERO;
public static final BigDecimal ONE;
public static final BigDecimal TEN;
public static final int ROUND_UP = 0;
public static final int ROUND_DOWN = 1;
public static final int ROUND_CEILING = 2;
public static final int ROUND_FLOOR = 3;
public static final int ROUND_HALF_UP = 4;
public static final int ROUND_HALF_DOWN = 5;
public static final int ROUND_HALF_EVEN = 6;
public static final int ROUND_UNNECESSARY = 7;
private static final long[] LONG_TEN_POWERS_TABLE;
private static volatile BigInteger[] BIG_TEN_POWERS_TABLE;
private static final int BIG_TEN_POWERS_TABLE_INITLEN;
private static final int BIG_TEN_POWERS_TABLE_MAX;
private static final long[] THRESHOLDS_TABLE;
BigDecimal(BigInteger paramBigInteger, long paramLong, int paramInt1, int paramInt2)
{
this.scale = paramInt1;
this.precision = paramInt2;
this.intCompact = paramLong;
this.intVal = paramBigInteger;
}
public BigDecimal(char[] paramArrayOfChar, int paramInt1, int paramInt2)
{
if ((paramInt1 + paramInt2 > paramArrayOfChar.length) || (paramInt1 < 0))
throw new NumberFormatException();
int i = 0;
int j = 0;
long l1 = 0L;
BigInteger localBigInteger = null;
try
{
int k = 0;
if (paramArrayOfChar[paramInt1] == '-')
{
k = 1;
++paramInt1;
--paramInt2;
}
else if (paramArrayOfChar[paramInt1] == '+')
{
++paramInt1;
--paramInt2;
}
int l = 0;
int i1 = paramInt1;
long l2 = 0L;
int i2 = (paramInt2 <= 18) ? 1 : 0;
char[] arrayOfChar1 = (i2 != 0) ? null : new char[paramInt2];
int i3 = 0;
while (paramInt2 > 0)
{
char c = paramArrayOfChar[paramInt1];
int i4;
if (((c >= '0') && (c <= '9')) || (Character.isDigit(c)))
{
if (i2 != 0)
{
i4 = Character.digit(c, 10);
if (i4 == 0)
{
if (i == 0)
{
i = 1;
}
else if (l1 != 0L)
{
l1 *= 10L;
++i;
}
}
else
{
if ((i != 1) || (l1 != 0L))
++i;
l1 = l1 * 10L + i4;
}
}
else if ((c == '0') || (Character.digit(c, 10) == 0))
{
if (i == 0)
{
arrayOfChar1[i3] = c;
i = 1;
}
else if (i3 != 0)
{
arrayOfChar1[(i3++)] = c;
++i;
}
}
else
{
if ((i != 1) || (i3 != 0))
++i;
arrayOfChar1[(i3++)] = c;
}
if (l != 0)
++j;
}
else if (c == '.')
{
if (l != 0)
throw new NumberFormatException();
l = 1;
}
else
{
if ((c != 'e') && (c != 'E'))
throw new NumberFormatException();
c = paramArrayOfChar[(++paramInt1)];
--paramInt2;
i4 = (c == '-') ? 1 : 0;
if ((i4 != 0) || (c == '+'))
{
c = paramArrayOfChar[(++paramInt1)];
--paramInt2;
}
if (paramInt2 <= 0)
throw new NumberFormatException();
while ((paramInt2 > 10) && (Character.digit(c, 10) == 0))
{
c = paramArrayOfChar[(++paramInt1)];
--paramInt2;
}
if (paramInt2 > 10)
throw new NumberFormatException();
while (true)
{
int i5;
if ((c >= '0') && (c <= '9'))
{
i5 = c - '0';
}
else
{
i5 = Character.digit(c, 10);
if (i5 < 0)
throw new NumberFormatException();
}
l2 = l2 * 10L + i5;
if (paramInt2 == 1)
break;
c = paramArrayOfChar[(++paramInt1)];
--paramInt2;
}
if (i4 != 0)
l2 = -l2;
if ((int)l2 == l2)
break;
throw new NumberFormatException();
}
++paramInt1;
--paramInt2;
}
if (i == 0)
throw new NumberFormatException();
if (l2 != 0L)
{
long l3 = j - l2;
if ((l3 > 2147483647L) || (l3 < -2147483648L))
throw new NumberFormatException("Scale out of range.");
j = (int)l3;
}
if (i2 != 0)
{
l1 = (k != 0) ? -l1 : l1;
}
else
{
char[] arrayOfChar2;
if (k == 0)
{
arrayOfChar2 = (arrayOfChar1.length != i) ? Arrays.copyOf(arrayOfChar1, i) : arrayOfChar1;
}
else
{
arrayOfChar2 = new char[i + 1];
arrayOfChar2[0] = '-';
System.arraycopy(arrayOfChar1, 0, arrayOfChar2, 1, i);
}
localBigInteger = new BigInteger(arrayOfChar2);
l1 = compactValFor(localBigInteger);
}
}
catch (ArrayIndexOutOfBoundsException localArrayIndexOutOfBoundsException)
{
throw new NumberFormatException();
}
catch (NegativeArraySizeException localNegativeArraySizeException)
{
throw new NumberFormatException();
}
this.scale = j;
this.precision = i;
this.intCompact = l1;
this.intVal = localBigInteger;
}
public BigDecimal(char[] paramArrayOfChar, int paramInt1, int paramInt2, MathContext paramMathContext)
{
this(paramArrayOfChar, paramInt1, paramInt2);
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(char[] paramArrayOfChar)
{
this(paramArrayOfChar, 0, paramArrayOfChar.length);
}
public BigDecimal(char[] paramArrayOfChar, MathContext paramMathContext)
{
this(paramArrayOfChar, 0, paramArrayOfChar.length, paramMathContext);
}
public BigDecimal(String paramString)
{
this(paramString.toCharArray(), 0, paramString.length());
}
public BigDecimal(String paramString, MathContext paramMathContext)
{
this(paramString.toCharArray(), 0, paramString.length());
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(double paramDouble)
{
if ((Double.isInfinite(paramDouble)) || (Double.isNaN(paramDouble)))
throw new NumberFormatException("Infinite or NaN");
long l1 = Double.doubleToLongBits(paramDouble);
int i = (l1 >> 63 == 0L) ? 1 : -1;
int j = (int)(l1 >> 52 & 0x7FF);
long l2 = (j == 0) ? (l1 & 0xFFFFFFFF) << 1 : l1 & 0xFFFFFFFF | 0x0;
j -= 1075;
if (l2 == 0L)
{
this.intVal = BigInteger.ZERO;
this.intCompact = 0L;
this.precision = 1;
return;
}
while ((l2 & 1L) == 0L)
{
l2 >>= 1;
++j;
}
this.intVal = BigInteger.valueOf(i * l2);
if (j < 0)
{
this.intVal = this.intVal.multiply(BigInteger.valueOf(5L).pow(-j));
this.scale = (-j);
}
else if (j > 0)
{
this.intVal = this.intVal.multiply(BigInteger.valueOf(2L).pow(j));
}
this.intCompact = compactValFor(this.intVal);
}
public BigDecimal(double paramDouble, MathContext paramMathContext)
{
this(paramDouble);
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(BigInteger paramBigInteger)
{
this.intVal = paramBigInteger;
this.intCompact = compactValFor(paramBigInteger);
}
public BigDecimal(BigInteger paramBigInteger, MathContext paramMathContext)
{
this(paramBigInteger);
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(BigInteger paramBigInteger, int paramInt)
{
this(paramBigInteger);
this.scale = paramInt;
}
public BigDecimal(BigInteger paramBigInteger, int paramInt, MathContext paramMathContext)
{
this(paramBigInteger);
this.scale = paramInt;
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(int paramInt)
{
this.intCompact = paramInt;
}
public BigDecimal(int paramInt, MathContext paramMathContext)
{
this.intCompact = paramInt;
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public BigDecimal(long paramLong)
{
this.intCompact = paramLong;
this.intVal = ((paramLong == -9223372036854775808L) ? BigInteger.valueOf(paramLong) : null);
}
public BigDecimal(long paramLong, MathContext paramMathContext)
{
this(paramLong);
if (paramMathContext.precision <= 0)
return;
roundThis(paramMathContext);
}
public static BigDecimal valueOf(long paramLong, int paramInt)
{
if (paramInt == 0)
return valueOf(paramLong);
if (paramLong == 0L)
{
if ((paramInt > 0) && (paramInt < ZERO_SCALED_BY.length))
return ZERO_SCALED_BY[paramInt];
return new BigDecimal(BigInteger.ZERO, 0L, paramInt, 1);
}
return new BigDecimal((paramLong == -9223372036854775808L) ? BigInteger.valueOf(paramLong) : null, paramLong, paramInt, 0);
}
public static BigDecimal valueOf(long paramLong)
{
if ((paramLong >= 0L) && (paramLong < zeroThroughTen.length))
return zeroThroughTen[(int)paramLong];
if (paramLong != -9223372036854775808L)
return new BigDecimal(null, paramLong, 0, 0);
return new BigDecimal(BigInteger.valueOf(paramLong), paramLong, 0, 0);
}
public static BigDecimal valueOf(double paramDouble)
{
return new BigDecimal(Double.toString(paramDouble));
}
public BigDecimal add(BigDecimal paramBigDecimal)
{
long l1 = this.intCompact;
long l2 = paramBigDecimal.intCompact;
BigInteger localBigInteger1 = (this.intCompact != -9223372036854775808L) ? null : this.intVal;
BigInteger localBigInteger2 = (paramBigDecimal.intCompact != -9223372036854775808L) ? null : paramBigDecimal.intVal;
int i = this.scale;
long l3 = i - paramBigDecimal.scale;
if (l3 != 0L)
{
int j;
if (l3 < 0L)
{
j = checkScale(-l3);
i = paramBigDecimal.scale;
if ((l1 == -9223372036854775808L) || ((l1 = longMultiplyPowerTen(l1, j)) == -9223372036854775808L))
localBigInteger1 = bigMultiplyPowerTen(j);
}
else
{
j = paramBigDecimal.checkScale(l3);
if ((l2 == -9223372036854775808L) || ((l2 = longMultiplyPowerTen(l2, j)) == -9223372036854775808L))
localBigInteger2 = paramBigDecimal.bigMultiplyPowerTen(j);
}
}
if ((l1 != -9223372036854775808L) && (l2 != -9223372036854775808L))
{
long l4 = l1 + l2;
if (((l4 ^ l1) & (l4 ^ l2)) >= 0L)
return valueOf(l4, i);
}
if (localBigInteger1 == null)
localBigInteger1 = BigInteger.valueOf(l1);
if (localBigInteger2 == null)
localBigInteger2 = BigInteger.valueOf(l2);
BigInteger localBigInteger3 = localBigInteger1.add(localBigInteger2);
return new BigDecimal(localBigInteger3, compactValFor(localBigInteger3), i, 0);
}
public BigDecimal add(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
if (paramMathContext.precision == 0)
return add(paramBigDecimal);
BigDecimal localBigDecimal1 = this;
inflate();
paramBigDecimal.inflate();
int i = (localBigDecimal1.signum() == 0) ? 1 : 0;
int j = (paramBigDecimal.signum() == 0) ? 1 : 0;
if ((i != 0) || (j != 0))
{
int k = Math.max(localBigDecimal1.scale(), paramBigDecimal.scale());
if ((i != 0) && (j != 0))
return new BigDecimal(BigInteger.ZERO, 0L, k, 0);
BigDecimal localBigDecimal2 = (i != 0) ? doRound(paramBigDecimal, paramMathContext) : doRound(localBigDecimal1, paramMathContext);
if (localBigDecimal2.scale() == k)
return localBigDecimal2;
if (localBigDecimal2.scale() > k)
{
BigDecimal localBigDecimal3 = new BigDecimal(localBigDecimal2.intVal, localBigDecimal2.intCompact, localBigDecimal2.scale, 0);
localBigDecimal3.stripZerosToMatchScale(k);
return localBigDecimal3;
}
int i1 = paramMathContext.precision - localBigDecimal2.precision();
int i2 = k - localBigDecimal2.scale();
if (i1 >= i2)
return localBigDecimal2.setScale(k);
return localBigDecimal2.setScale(localBigDecimal2.scale() + i1);
}
long l = localBigDecimal1.scale - paramBigDecimal.scale;
if (l != 0L)
{
localObject = preAlign(localBigDecimal1, paramBigDecimal, l, paramMathContext);
matchScale(localObject);
localBigDecimal1 = localObject[0];
paramBigDecimal = localObject[1];
}
Object localObject = new BigDecimal(localBigDecimal1.inflate().add(paramBigDecimal.inflate()), localBigDecimal1.scale);
return ((BigDecimal)doRound((BigDecimal)localObject, paramMathContext));
}
private BigDecimal[] preAlign(BigDecimal paramBigDecimal1, BigDecimal paramBigDecimal2, long paramLong, MathContext paramMathContext)
{
assert (paramLong != 0L);
BigDecimal localBigDecimal1;
BigDecimal localBigDecimal2;
if (paramLong < 0L)
{
localBigDecimal1 = paramBigDecimal1;
localBigDecimal2 = paramBigDecimal2;
}
else
{
localBigDecimal1 = paramBigDecimal2;
localBigDecimal2 = paramBigDecimal1;
}
long l1 = localBigDecimal1.scale - localBigDecimal1.precision() + paramMathContext.precision;
long l2 = localBigDecimal2.scale - localBigDecimal2.precision() + 1L;
if ((l2 > localBigDecimal1.scale + 2) && (l2 > l1 + 2L))
localBigDecimal2 = valueOf(localBigDecimal2.signum(), checkScale(Math.max(localBigDecimal1.scale, l1) + 3L));
BigDecimal[] arrayOfBigDecimal = { localBigDecimal1, localBigDecimal2 };
return arrayOfBigDecimal;
}
public BigDecimal subtract(BigDecimal paramBigDecimal)
{
return add(paramBigDecimal.negate());
}
public BigDecimal subtract(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
BigDecimal localBigDecimal = paramBigDecimal.negate();
if (paramMathContext.precision == 0)
return add(localBigDecimal);
return add(localBigDecimal, paramMathContext);
}
public BigDecimal multiply(BigDecimal paramBigDecimal)
{
long l1 = this.intCompact;
long l2 = paramBigDecimal.intCompact;
int i = checkScale(this.scale + paramBigDecimal.scale);
if ((l1 != -9223372036854775808L) && (l2 != -9223372036854775808L))
{
long l3 = l1 * l2;
if (((Math.abs(l1) >>> 31 == 0L) && (Math.abs(l2) >>> 31 == 0L)) || (l2 == 0L) || (l3 / l2 == l1))
return valueOf(l3, i);
return new BigDecimal(BigInteger.valueOf(l1).multiply(l2), -9223372036854775808L, i, 0);
}
BigInteger localBigInteger;
if ((l1 == -9223372036854775808L) && (l2 == -9223372036854775808L))
localBigInteger = this.intVal.multiply(paramBigDecimal.intVal);
else if (l1 != -9223372036854775808L)
localBigInteger = paramBigDecimal.intVal.multiply(l1);
else
localBigInteger = this.intVal.multiply(l2);
return new BigDecimal(localBigInteger, -9223372036854775808L, i, 0);
}
public BigDecimal multiply(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
if (paramMathContext.precision == 0)
return multiply(paramBigDecimal);
return doRound(multiply(paramBigDecimal), paramMathContext);
}
public BigDecimal divide(BigDecimal paramBigDecimal, int paramInt1, int paramInt2)
{
if ((paramInt2 < 0) || (paramInt2 > 7))
throw new IllegalArgumentException("Invalid rounding mode");
BigDecimal localBigDecimal = this;
if (checkScale(paramInt1 + paramBigDecimal.scale) > this.scale)
localBigDecimal = setScale(paramInt1 + paramBigDecimal.scale, 7);
else
paramBigDecimal = paramBigDecimal.setScale(checkScale(this.scale - paramInt1), 7);
return divideAndRound(localBigDecimal.intCompact, localBigDecimal.intVal, paramBigDecimal.intCompact, paramBigDecimal.intVal, paramInt1, paramInt2, paramInt1);
}
private static BigDecimal divideAndRound(long paramLong1, BigInteger paramBigInteger1, long paramLong2, BigInteger paramBigInteger2, int paramInt1, int paramInt2, int paramInt3)
{
long l1 = 0L;
long l2 = 0L;
MutableBigInteger localMutableBigInteger1 = null;
MutableBigInteger localMutableBigInteger2 = null;
MutableBigInteger localMutableBigInteger3 = null;
int j = ((paramLong1 != -9223372036854775808L) && (paramLong2 != -9223372036854775808L)) ? 1 : 0;
boolean bool1;
int i;
if (j != 0)
{
l1 = paramLong1 / paramLong2;
if ((paramInt2 == 1) && (paramInt1 == paramInt3))
return new BigDecimal(null, l1, paramInt1, 0);
l2 = paramLong1 % paramLong2;
bool1 = l2 == 0L;
i = (((paramLong1 < 0L) ? 1 : 0) == ((paramLong2 < 0L) ? 1 : 0)) ? 1 : -1;
}
else
{
if (paramBigInteger1 == null)
paramBigInteger1 = BigInteger.valueOf(paramLong1);
MutableBigInteger localMutableBigInteger4 = new MutableBigInteger(paramBigInteger1.mag);
localMutableBigInteger1 = new MutableBigInteger();
if (paramLong2 != -9223372036854775808L)
{
l2 = localMutableBigInteger4.divide(paramLong2, localMutableBigInteger1);
bool1 = l2 == 0L;
i = (paramLong2 < 0L) ? -paramBigInteger1.signum : paramBigInteger1.signum;
}
else
{
localMutableBigInteger3 = new MutableBigInteger(paramBigInteger2.mag);
localMutableBigInteger2 = localMutableBigInteger4.divide(localMutableBigInteger3, localMutableBigInteger1);
bool1 = localMutableBigInteger2.isZero();
i = (paramBigInteger1.signum != paramBigInteger2.signum) ? -1 : 1;
}
}
boolean bool2 = false;
if (!(bool1))
{
if (paramInt2 == 7)
throw new ArithmeticException("Rounding necessary");
if (paramInt2 == 0)
{
bool2 = true;
}
else if (paramInt2 == 1)
{
bool2 = false;
}
else if (paramInt2 == 2)
{
bool2 = i > 0;
}
else if (paramInt2 == 3)
{
bool2 = i < 0;
}
else
{
int k;
if ((j != 0) || (paramLong2 != -9223372036854775808L))
if ((l2 <= -4611686018427387904L) || (l2 > 4611686018427387903L))
k = 1;
else
k = longCompareMagnitude(2L * l2, paramLong2);
else
k = localMutableBigInteger2.compareHalf(localMutableBigInteger3);
if (k < 0)
bool2 = false;
else if (k > 0)
bool2 = true;
else if (paramInt2 == 4)
bool2 = true;
else if (paramInt2 == 5)
bool2 = false;
else
bool2 = (j != 0) ? false : ((l1 & 1L) != 0L) ? true : localMutableBigInteger1.isOdd();
}
}
BigDecimal localBigDecimal;
if (j != 0)
{
localBigDecimal = new BigDecimal(null, (bool2) ? l1 + i : l1, paramInt1, 0);
}
else
{
if (bool2)
localMutableBigInteger1.add(MutableBigInteger.ONE);
localBigDecimal = localMutableBigInteger1.toBigDecimal(i, paramInt1);
}
if ((bool1) && (paramInt3 != paramInt1))
localBigDecimal.stripZerosToMatchScale(paramInt3);
return localBigDecimal;
}
public BigDecimal divide(BigDecimal paramBigDecimal, int paramInt, RoundingMode paramRoundingMode)
{
return divide(paramBigDecimal, paramInt, paramRoundingMode.oldMode);
}
public BigDecimal divide(BigDecimal paramBigDecimal, int paramInt)
{
return divide(paramBigDecimal, this.scale, paramInt);
}
public BigDecimal divide(BigDecimal paramBigDecimal, RoundingMode paramRoundingMode)
{
return divide(paramBigDecimal, this.scale, paramRoundingMode.oldMode);
}
public BigDecimal divide(BigDecimal paramBigDecimal)
{
if (paramBigDecimal.signum() == 0)
{
if (signum() == 0)
throw new ArithmeticException("Division undefined");
throw new ArithmeticException("Division by zero");
}
int i = saturateLong(this.scale - paramBigDecimal.scale);
if (signum() == 0)
return (((0 <= i) && (i < ZERO_SCALED_BY.length)) ? ZERO_SCALED_BY[i] : valueOf(0L, i));
inflate();
paramBigDecimal.inflate();
MathContext localMathContext = new MathContext((int)Math.min(precision() + ()Math.ceil(10.0D * paramBigDecimal.precision() / 3.0D), 2147483647L), RoundingMode.UNNECESSARY);
BigDecimal localBigDecimal;
try
{
localBigDecimal = divide(paramBigDecimal, localMathContext);
}
catch (ArithmeticException localArithmeticException)
{
throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result.");
}
int j = localBigDecimal.scale();
if (i > j)
return localBigDecimal.setScale(i, 7);
return localBigDecimal;
}
public BigDecimal divide(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
int i = paramMathContext.precision;
if (i == 0)
return divide(paramBigDecimal);
BigDecimal localBigDecimal1 = this;
long l = localBigDecimal1.scale - paramBigDecimal.scale;
if (paramBigDecimal.signum() == 0)
{
if (localBigDecimal1.signum() == 0)
throw new ArithmeticException("Division undefined");
throw new ArithmeticException("Division by zero");
}
if (localBigDecimal1.signum() == 0)
return new BigDecimal(BigInteger.ZERO, 0L, saturateLong(l), 1);
int j = localBigDecimal1.precision();
int k = paramBigDecimal.precision();
localBigDecimal1 = new BigDecimal(localBigDecimal1.intVal, localBigDecimal1.intCompact, j, j);
paramBigDecimal = new BigDecimal(paramBigDecimal.intVal, paramBigDecimal.intCompact, k, k);
if (localBigDecimal1.compareMagnitude(paramBigDecimal) > 0)
k = --paramBigDecimal.scale;
int i1 = checkScale(l + k - j + i);
if (checkScale(i + k) > j)
localBigDecimal1 = localBigDecimal1.setScale(i + k, 7);
else
paramBigDecimal = paramBigDecimal.setScale(checkScale(j - i), 7);
BigDecimal localBigDecimal2 = divideAndRound(localBigDecimal1.intCompact, localBigDecimal1.intVal, paramBigDecimal.intCompact, paramBigDecimal.intVal, i1, paramMathContext.roundingMode.oldMode, checkScale(l));
localBigDecimal2 = doRound(localBigDecimal2, paramMathContext);
return localBigDecimal2;
}
public BigDecimal divideToIntegralValue(BigDecimal paramBigDecimal)
{
int i = saturateLong(this.scale - paramBigDecimal.scale);
if (compareMagnitude(paramBigDecimal) < 0)
return valueOf(0L, i);
if ((signum() == 0) && (paramBigDecimal.signum() != 0))
return setScale(i, 7);
int j = (int)Math.min(precision() + ()Math.ceil(10.0D * paramBigDecimal.precision() / 3.0D) + Math.abs(scale() - paramBigDecimal.scale()) + 2L, 2147483647L);
BigDecimal localBigDecimal = divide(paramBigDecimal, new MathContext(j, RoundingMode.DOWN));
if (localBigDecimal.scale > 0)
{
localBigDecimal = localBigDecimal.setScale(0, RoundingMode.DOWN);
localBigDecimal.stripZerosToMatchScale(i);
}
if (localBigDecimal.scale < i)
localBigDecimal = localBigDecimal.setScale(i, 7);
return localBigDecimal;
}
public BigDecimal divideToIntegralValue(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
if ((paramMathContext.precision == 0) || (compareMagnitude(paramBigDecimal) < 0))
return divideToIntegralValue(paramBigDecimal);
int i = saturateLong(this.scale - paramBigDecimal.scale);
BigDecimal localBigDecimal1 = divide(paramBigDecimal, new MathContext(paramMathContext.precision, RoundingMode.DOWN));
if (localBigDecimal1.scale() < 0)
{
BigDecimal localBigDecimal2 = localBigDecimal1.multiply(paramBigDecimal);
if (subtract(localBigDecimal2).compareMagnitude(paramBigDecimal) >= 0)
throw new ArithmeticException("Division impossible");
}
else if (localBigDecimal1.scale() > 0)
{
localBigDecimal1 = localBigDecimal1.setScale(0, RoundingMode.DOWN);
}
int j;
if ((i > localBigDecimal1.scale()) && ((j = paramMathContext.precision - localBigDecimal1.precision()) > 0))
return localBigDecimal1.setScale(localBigDecimal1.scale() + Math.min(j, i - localBigDecimal1.scale));
localBigDecimal1.stripZerosToMatchScale(i);
return localBigDecimal1;
}
public BigDecimal remainder(BigDecimal paramBigDecimal)
{
BigDecimal[] arrayOfBigDecimal = divideAndRemainder(paramBigDecimal);
return arrayOfBigDecimal[1];
}
public BigDecimal remainder(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
BigDecimal[] arrayOfBigDecimal = divideAndRemainder(paramBigDecimal, paramMathContext);
return arrayOfBigDecimal[1];
}
public BigDecimal[] divideAndRemainder(BigDecimal paramBigDecimal)
{
BigDecimal[] arrayOfBigDecimal = new BigDecimal[2];
arrayOfBigDecimal[0] = divideToIntegralValue(paramBigDecimal);
arrayOfBigDecimal[1] = subtract(arrayOfBigDecimal[0].multiply(paramBigDecimal));
return arrayOfBigDecimal;
}
public BigDecimal[] divideAndRemainder(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
if (paramMathContext.precision == 0)
return divideAndRemainder(paramBigDecimal);
BigDecimal[] arrayOfBigDecimal = new BigDecimal[2];
BigDecimal localBigDecimal = this;
arrayOfBigDecimal[0] = localBigDecimal.divideToIntegralValue(paramBigDecimal, paramMathContext);
arrayOfBigDecimal[1] = localBigDecimal.subtract(arrayOfBigDecimal[0].multiply(paramBigDecimal));
return arrayOfBigDecimal;
}
public BigDecimal pow(int paramInt)
{
if ((paramInt < 0) || (paramInt > 999999999))
throw new ArithmeticException("Invalid operation");
int i = checkScale(this.scale * paramInt);
inflate();
return new BigDecimal(this.intVal.pow(paramInt), i);
}
public BigDecimal pow(int paramInt, MathContext paramMathContext)
{
if (paramMathContext.precision == 0)
return pow(paramInt);
if ((paramInt < -999999999) || (paramInt > 999999999))
throw new ArithmeticException("Invalid operation");
if (paramInt == 0)
return ONE;
inflate();
BigDecimal localBigDecimal1 = this;
MathContext localMathContext = paramMathContext;
int i = Math.abs(paramInt);
if (paramMathContext.precision > 0)
{
int k = longDigitLength(i);
if (k > paramMathContext.precision)
throw new ArithmeticException("Invalid operation");
localMathContext = new MathContext(paramMathContext.precision + k + 1, paramMathContext.roundingMode);
}
BigDecimal localBigDecimal2 = ONE;
int l = 0;
for (int i1 = 1; ; ++i1)
{
int j;
i += i;
if (j < 0)
{
l = 1;
localBigDecimal2 = localBigDecimal2.multiply(localBigDecimal1, localMathContext);
}
if (i1 == 31)
break;
if (l == 0)
continue;
localBigDecimal2 = localBigDecimal2.multiply(localBigDecimal2, localMathContext);
}
if (paramInt < 0)
localBigDecimal2 = ONE.divide(localBigDecimal2, localMathContext);
return doRound(localBigDecimal2, paramMathContext);
}
public BigDecimal abs()
{
return ((signum() < 0) ? negate() : this);
}
public BigDecimal abs(MathContext paramMathContext)
{
return ((signum() < 0) ? negate(paramMathContext) : plus(paramMathContext));
}
public BigDecimal negate()
{
long l;
BigInteger localBigInteger;
if (this.intCompact == -9223372036854775808L)
{
l = -9223372036854775808L;
localBigInteger = this.intVal.negate();
}
else
{
l = -this.intCompact;
localBigInteger = null;
}
return new BigDecimal(localBigInteger, l, this.scale, this.precision);
}
public BigDecimal negate(MathContext paramMathContext)
{
return negate().plus(paramMathContext);
}
public BigDecimal plus()
{
return this;
}
public BigDecimal plus(MathContext paramMathContext)
{
if (paramMathContext.precision == 0)
return this;
return doRound(this, paramMathContext);
}
public int signum()
{
return ((this.intCompact != -9223372036854775808L) ? Long.signum(this.intCompact) : this.intVal.signum());
}
public int scale()
{
return this.scale;
}
public int precision()
{
int i = this.precision;
if (i == 0)
{
long l = this.intCompact;
if (l != -9223372036854775808L)
i = longDigitLength(l);
else
i = bigDigitLength(inflate());
this.precision = i;
}
return i;
}
public BigInteger unscaledValue()
{
return inflate();
}
public BigDecimal round(MathContext paramMathContext)
{
return plus(paramMathContext);
}
public BigDecimal setScale(int paramInt, RoundingMode paramRoundingMode)
{
return setScale(paramInt, paramRoundingMode.oldMode);
}
public BigDecimal setScale(int paramInt1, int paramInt2)
{
if ((paramInt2 < 0) || (paramInt2 > 7))
throw new IllegalArgumentException("Invalid rounding mode");
int i = this.scale;
if (paramInt1 == i)
return this;
if (signum() == 0)
return valueOf(0L, paramInt1);
long l = this.intCompact;
if (paramInt1 > i)
{
j = checkScale(paramInt1 - i);
BigInteger localBigInteger = null;
if ((l == -9223372036854775808L) || ((l = longMultiplyPowerTen(l, j)) == -9223372036854775808L))
localBigInteger = bigMultiplyPowerTen(j);
return new BigDecimal(localBigInteger, l, paramInt1, (this.precision > 0) ? this.precision + j : 0);
}
int j = checkScale(i - paramInt1);
if (j < LONG_TEN_POWERS_TABLE.length)
return divideAndRound(l, this.intVal, LONG_TEN_POWERS_TABLE[j], null, paramInt1, paramInt2, paramInt1);
return divideAndRound(l, this.intVal, -9223372036854775808L, bigTenToThe(j), paramInt1, paramInt2, paramInt1);
}
public BigDecimal setScale(int paramInt)
{
return setScale(paramInt, 7);
}
public BigDecimal movePointLeft(int paramInt)
{
int i = checkScale(this.scale + paramInt);
BigDecimal localBigDecimal = new BigDecimal(this.intVal, this.intCompact, i, 0);
return ((localBigDecimal.scale < 0) ? localBigDecimal.setScale(0, 7) : localBigDecimal);
}
public BigDecimal movePointRight(int paramInt)
{
int i = checkScale(this.scale - paramInt);
BigDecimal localBigDecimal = new BigDecimal(this.intVal, this.intCompact, i, 0);
return ((localBigDecimal.scale < 0) ? localBigDecimal.setScale(0, 7) : localBigDecimal);
}
public BigDecimal scaleByPowerOfTen(int paramInt)
{
return new BigDecimal(this.intVal, this.intCompact, checkScale(this.scale - paramInt), this.precision);
}
public BigDecimal stripTrailingZeros()
{
inflate();
BigDecimal localBigDecimal = new BigDecimal(this.intVal, this.scale);
localBigDecimal.stripZerosToMatchScale(-9223372036854775808L);
return localBigDecimal;
}
public int compareTo(BigDecimal paramBigDecimal)
{
if (this.scale == paramBigDecimal.scale)
{
long l1 = this.intCompact;
long l2 = paramBigDecimal.intCompact;
if ((l1 != -9223372036854775808L) && (l2 != -9223372036854775808L))
return ((l1 != l2) ? -1 : (l1 > l2) ? 1 : 0);
}
int i = signum();
int j = paramBigDecimal.signum();
if (i != j)
return ((i > j) ? 1 : -1);
if (i == 0)
return 0;
int k = compareMagnitude(paramBigDecimal);
return ((i > 0) ? k : -k);
}
private int compareMagnitude(BigDecimal paramBigDecimal)
{
long l1 = paramBigDecimal.intCompact;
long l2 = this.intCompact;
if (l2 == 0L)
return ((l1 == 0L) ? 0 : -1);
if (l1 == 0L)
return 1;
int i = this.scale - paramBigDecimal.scale;
if (i != 0)
{
int j = precision() - this.scale;
int k = paramBigDecimal.precision() - paramBigDecimal.scale;
if (j < k)
return -1;
if (j > k)
return 1;
BigInteger localBigInteger = null;
if (i < 0)
{
if ((((l2 == -9223372036854775808L) || ((l2 = longMultiplyPowerTen(l2, -i)) == -9223372036854775808L))) && (l1 == -9223372036854775808L))
{
localBigInteger = bigMultiplyPowerTen(-i);
return localBigInteger.compareMagnitude(paramBigDecimal.intVal);
}
}
else if ((((l1 == -9223372036854775808L) || ((l1 = longMultiplyPowerTen(l1, i)) == -9223372036854775808L))) && (l2 == -9223372036854775808L))
{
localBigInteger = paramBigDecimal.bigMultiplyPowerTen(i);
return this.intVal.compareMagnitude(localBigInteger);
}
}
if (l2 != -9223372036854775808L)
return ((l1 != -9223372036854775808L) ? longCompareMagnitude(l2, l1) : -1);
if (l1 != -9223372036854775808L)
return 1;
return this.intVal.compareMagnitude(paramBigDecimal.intVal);
}
public boolean equals(Object paramObject)
{
if (!(paramObject instanceof BigDecimal))
return false;
BigDecimal localBigDecimal = (BigDecimal)paramObject;
if (paramObject == this)
return true;
if (this.scale != localBigDecimal.scale)
return false;
long l1 = this.intCompact;
long l2 = localBigDecimal.intCompact;
if (l1 != -9223372036854775808L)
{
if (l2 == -9223372036854775808L)
l2 = compactValFor(localBigDecimal.intVal);
return (l2 == l1);
}
if (l2 != -9223372036854775808L)
return (l2 == compactValFor(this.intVal));
return inflate().equals(localBigDecimal.inflate());
}
public BigDecimal min(BigDecimal paramBigDecimal)
{
return ((compareTo(paramBigDecimal) <= 0) ? this : paramBigDecimal);
}
public BigDecimal max(BigDecimal paramBigDecimal)
{
return ((compareTo(paramBigDecimal) >= 0) ? this : paramBigDecimal);
}
public int hashCode()
{
if (this.intCompact != -9223372036854775808L)
{
long l = (this.intCompact < 0L) ? -this.intCompact : this.intCompact;
int i = (int)((int)(l >>> 32) * 31 + (l & 0xFFFFFFFF));
return (31 * ((this.intCompact < 0L) ? -i : i) + this.scale);
}
return (31 * this.intVal.hashCode() + this.scale);
}
public String toString()
{
String str = this.stringCache;
if (str == null)
this.stringCache = (str = layoutChars(true));
return str;
}
public String toEngineeringString()
{
return layoutChars(false);
}
public String toPlainString()
{
BigDecimal localBigDecimal = this;
if (localBigDecimal.scale < 0)
localBigDecimal = localBigDecimal.setScale(0);
localBigDecimal.inflate();
if (localBigDecimal.scale == 0)
return localBigDecimal.intVal.toString();
return localBigDecimal.getValueString(localBigDecimal.signum(), localBigDecimal.intVal.abs().toString(), localBigDecimal.scale);
}
private String getValueString(int paramInt1, String paramString, int paramInt2)
{
int i = paramString.length() - paramInt2;
if (i == 0)
return ((paramInt1 < 0) ? "-0." : "0.") + paramString;
StringBuilder localStringBuilder;
if (i > 0)
{
localStringBuilder = new StringBuilder(paramString);
localStringBuilder.insert(i, '.');
if (paramInt1 < 0)
localStringBuilder.insert(0, '-');
}
else
{
localStringBuilder = new StringBuilder(3 - i + paramString.length());
localStringBuilder.append((paramInt1 < 0) ? "-0." : "0.");
for (int j = 0; j < -i; ++j)
localStringBuilder.append('0');
localStringBuilder.append(paramString);
}
return localStringBuilder.toString();
}
public BigInteger toBigInteger()
{
return setScale(0, 1).inflate();
}
public BigInteger toBigIntegerExact()
{
return setScale(0, 7).inflate();
}
public long longValue()
{
return (((this.intCompact != -9223372036854775808L) && (this.scale == 0)) ? this.intCompact : toBigInteger().longValue());
}
public long longValueExact()
{
if ((this.intCompact != -9223372036854775808L) && (this.scale == 0))
return this.intCompact;
if (precision() - this.scale > 19)
throw new ArithmeticException("Overflow");
if (signum() == 0)
return 0L;
if (precision() - this.scale <= 0)
throw new ArithmeticException("Rounding necessary");
BigDecimal localBigDecimal = setScale(0, 7);
if (localBigDecimal.precision() >= 19)
LongOverflow.check(localBigDecimal);
return localBigDecimal.inflate().longValue();
}
public int intValue()
{
return (((this.intCompact != -9223372036854775808L) && (this.scale == 0)) ? (int)this.intCompact : toBigInteger().intValue());
}
public int intValueExact()
{
long l = longValueExact();
if ((int)l != l)
throw new ArithmeticException("Overflow");
return (int)l;
}
public short shortValueExact()
{
long l = longValueExact();
if ((short)(int)l != l)
throw new ArithmeticException("Overflow");
return (short)(int)l;
}
public byte byteValueExact()
{
long l = longValueExact();
if ((byte)(int)l != l)
throw new ArithmeticException("Overflow");
return (byte)(int)l;
}
public float floatValue()
{
if ((this.scale == 0) && (this.intCompact != -9223372036854775808L))
return (float)this.intCompact;
return Float.parseFloat(toString());
}
public double doubleValue()
{
if ((this.scale == 0) && (this.intCompact != -9223372036854775808L))
return this.intCompact;
return Double.parseDouble(toString());
}
public BigDecimal ulp()
{
return valueOf(1L, scale());
}
private String layoutChars(boolean paramBoolean)
{
if (this.scale == 0)
return ((this.intCompact != -9223372036854775808L) ? Long.toString(this.intCompact) : this.intVal.toString());
StringBuilderHelper localStringBuilderHelper = (StringBuilderHelper)threadLocalStringBuilderHelper.get();
int i;
char[] arrayOfChar;
if (this.intCompact != -9223372036854775808L)
{
i = localStringBuilderHelper.putIntCompact(Math.abs(this.intCompact));
arrayOfChar = localStringBuilderHelper.getCompactCharArray();
}
else
{
i = 0;
arrayOfChar = this.intVal.abs().toString().toCharArray();
}
StringBuilder localStringBuilder = localStringBuilderHelper.getStringBuilder();
if (signum() < 0)
localStringBuilder.append('-');
int j = arrayOfChar.length - i;
long l = -this.scale + j - 1;
int k;
if ((this.scale >= 0) && (l >= -6L))
{
k = this.scale - j;
if (k >= 0)
{
localStringBuilder.append('0');
localStringBuilder.append('.');
while (k > 0)
{
localStringBuilder.append('0');
--k;
}
localStringBuilder.append(arrayOfChar, i, j);
}
else
{
localStringBuilder.append(arrayOfChar, i, -k);
localStringBuilder.append('.');
localStringBuilder.append(arrayOfChar, -k + i, this.scale);
}
}
else
{
if (paramBoolean)
{
localStringBuilder.append(arrayOfChar[i]);
if (j > 1)
{
localStringBuilder.append('.');
localStringBuilder.append(arrayOfChar, i + 1, j - 1);
}
}
else
{
k = (int)(l % 3L);
if (k < 0);
l -= (k += 3);
++k;
if (signum() == 0);
switch (k)
{
case 1:
localStringBuilder.append('0');
break;
case 2:
localStringBuilder.append("0.00");
l += 3L;
break;
case 3:
localStringBuilder.append("0.0");
l += 3L;
break;
default:
throw new AssertionError("Unexpected sig value " + k);
if (k >= j)
{
localStringBuilder.append(arrayOfChar, i, j);
for (int i1 = k - j; i1 > 0; --i1)
localStringBuilder.append('0');
}
else
{
localStringBuilder.append(arrayOfChar, i, k);
localStringBuilder.append('.');
localStringBuilder.append(arrayOfChar, i + k, j - k);
}
}
}
if (l != 0L)
{
localStringBuilder.append('E');
if (l > 0L)
localStringBuilder.append('+');
localStringBuilder.append(l);
}
}
return localStringBuilder.toString();
}
private static BigInteger bigTenToThe(int paramInt)
{
if (paramInt < 0)
return BigInteger.ZERO;
if (paramInt < BIG_TEN_POWERS_TABLE_MAX)
{
localObject = BIG_TEN_POWERS_TABLE;
if (paramInt < localObject.length)
return localObject[paramInt];
return expandBigIntegerTenPowers(paramInt);
}
Object localObject = new char[paramInt + 1];
localObject[0] = 49;
for (int i = 1; i <= paramInt; ++i)
localObject[i] = 48;
return ((BigInteger)new BigInteger(localObject));
}
private static BigInteger expandBigIntegerTenPowers(int paramInt)
{
synchronized (BigDecimal.class)
{
BigInteger[] arrayOfBigInteger = BIG_TEN_POWERS_TABLE;
int i = arrayOfBigInteger.length;
if (i <= paramInt)
{
int j = i << 1;
while (j <= paramInt)
j <<= 1;
arrayOfBigInteger = (BigInteger[])Arrays.copyOf(arrayOfBigInteger, j);
for (int k = i; k < j; ++k)
arrayOfBigInteger[k] = arrayOfBigInteger[(k - 1)].multiply(BigInteger.TEN);
BIG_TEN_POWERS_TABLE = arrayOfBigInteger;
}
return arrayOfBigInteger[paramInt];
}
}
private static long longMultiplyPowerTen(long paramLong, int paramInt)
{
if ((paramLong == 0L) || (paramInt <= 0))
return paramLong;
long[] arrayOfLong1 = LONG_TEN_POWERS_TABLE;
long[] arrayOfLong2 = THRESHOLDS_TABLE;
if ((paramInt < arrayOfLong1.length) && (paramInt < arrayOfLong2.length))
{
long l = arrayOfLong1[paramInt];
if (paramLong == 1L)
return l;
if (Math.abs(paramLong) <= arrayOfLong2[paramInt])
return (paramLong * l);
}
return -9223372036854775808L;
}
private BigInteger bigMultiplyPowerTen(int paramInt)
{
if (paramInt <= 0)
return inflate();
if (this.intCompact != -9223372036854775808L)
return bigTenToThe(paramInt).multiply(this.intCompact);
return this.intVal.multiply(bigTenToThe(paramInt));
}
private BigInteger inflate()
{
if (this.intVal == null)
this.intVal = BigInteger.valueOf(this.intCompact);
return this.intVal;
}
private static void matchScale(BigDecimal[] paramArrayOfBigDecimal)
{
if (paramArrayOfBigDecimal[0].scale == paramArrayOfBigDecimal[1].scale)
return;
if (paramArrayOfBigDecimal[0].scale < paramArrayOfBigDecimal[1].scale)
{
paramArrayOfBigDecimal[0] = paramArrayOfBigDecimal[0].setScale(paramArrayOfBigDecimal[1].scale, 7);
}
else
{
if (paramArrayOfBigDecimal[1].scale >= paramArrayOfBigDecimal[0].scale)
return;
paramArrayOfBigDecimal[1] = paramArrayOfBigDecimal[1].setScale(paramArrayOfBigDecimal[0].scale, 7);
}
}
private void readObject(ObjectInputStream paramObjectInputStream)
throws IOException, ClassNotFoundException
{
paramObjectInputStream.defaultReadObject();
if (this.intVal == null)
{
String str = "BigDecimal: null intVal in stream";
throw new StreamCorruptedException(str);
}
this.intCompact = compactValFor(this.intVal);
}
private void writeObject(ObjectOutputStream paramObjectOutputStream)
throws IOException
{
inflate();
paramObjectOutputStream.defaultWriteObject();
}
private static int longDigitLength(long paramLong)
{
assert (paramLong != -9223372036854775808L);
if (paramLong < 0L)
paramLong = -paramLong;
if (paramLong < 10L)
return 1;
int i = 64;
int j = (int)(paramLong >>> 32);
if (j == 0)
{
i -= 32;
j = (int)paramLong;
}
if (j >>> 16 == 0)
{
i -= 16;
j <<= 16;
}
if (j >>> 24 == 0)
{
i -= 8;
j <<= 8;
}
if (j >>> 28 == 0)
{
i -= 4;
j <<= 4;
}
if (j >>> 30 == 0)
{
i -= 2;
j <<= 2;
}
int k = ((j >>> 31) + i) * 1233 >>> 12;
long[] arrayOfLong = LONG_TEN_POWERS_TABLE;
return (((k >= arrayOfLong.length) || (paramLong < arrayOfLong[k])) ? k : k + 1);
}
private static int bigDigitLength(BigInteger paramBigInteger)
{
if (paramBigInteger.signum == 0)
return 1;
int i = (int)((paramBigInteger.bitLength() + 1L) * 646456993L >>> 31);
return ((paramBigInteger.compareMagnitude(bigTenToThe(i)) < 0) ? i : i + 1);
}
private BigDecimal stripZerosToMatchScale(long paramLong)
{
int i = (this.intCompact != -9223372036854775808L) ? 1 : 0;
inflate();
while ((this.intVal.compareMagnitude(BigInteger.TEN) >= 0) && (this.scale > paramLong))
{
if (this.intVal.testBit(0))
break;
BigInteger[] arrayOfBigInteger = this.intVal.divideAndRemainder(BigInteger.TEN);
if (arrayOfBigInteger[1].signum() != 0)
break;
this.intVal = arrayOfBigInteger[0];
this.scale = checkScale(this.scale - 1L);
if (this.precision <= 0)
continue;
this.precision -= 1;
}
if (this.intVal != null)
this.intCompact = compactValFor(this.intVal);
return this;
}
private int checkScale(long paramLong)
{
int i = (int)paramLong;
if (i != paramLong)
{
i = (paramLong > 2147483647L) ? 2147483647 : -2147483648;
BigInteger localBigInteger;
if ((this.intCompact != 0L) && ((((localBigInteger = this.intVal) == null) || (localBigInteger.signum() != 0))))
throw new ArithmeticException((i > 0) ? "Underflow" : "Overflow");
}
return i;
}
private BigDecimal roundOp(MathContext paramMathContext)
{
BigDecimal localBigDecimal = doRound(this, paramMathContext);
return localBigDecimal;
}
private void roundThis(MathContext paramMathContext)
{
BigDecimal localBigDecimal = doRound(this, paramMathContext);
if (localBigDecimal == this)
return;
this.intVal = localBigDecimal.intVal;
this.intCompact = localBigDecimal.intCompact;
this.scale = localBigDecimal.scale;
this.precision = localBigDecimal.precision;
}
private static BigDecimal doRound(BigDecimal paramBigDecimal, MathContext paramMathContext)
{
int i = paramMathContext.precision;
while ((j = paramBigDecimal.precision() - i) > 0)
{
int j;
int k = paramBigDecimal.checkScale(paramBigDecimal.scale - j);
int l = paramMathContext.roundingMode.oldMode;
if (j < LONG_TEN_POWERS_TABLE.length)
paramBigDecimal = divideAndRound(paramBigDecimal.intCompact, paramBigDecimal.intVal, LONG_TEN_POWERS_TABLE[j], null, k, l, k);
else
paramBigDecimal = divideAndRound(paramBigDecimal.intCompact, paramBigDecimal.intVal, -9223372036854775808L, bigTenToThe(j), k, l, k);
}
return paramBigDecimal;
}
private static long compactValFor(BigInteger paramBigInteger)
{
int[] arrayOfInt = paramBigInteger.mag;
int i = arrayOfInt.length;
if (i == 0)
return 0L;
int j = arrayOfInt[0];
if ((i > 2) || ((i == 2) && (j < 0)))
return -9223372036854775808L;
long l = (i == 2) ? (arrayOfInt[1] & 0xFFFFFFFF) + (j << 32) : j & 0xFFFFFFFF;
return ((paramBigInteger.signum < 0) ? -l : l);
}
private static int longCompareMagnitude(long paramLong1, long paramLong2)
{
if (paramLong1 < 0L)
paramLong1 = -paramLong1;
if (paramLong2 < 0L)
paramLong2 = -paramLong2;
return ((paramLong1 == paramLong2) ? 0 : (paramLong1 < paramLong2) ? -1 : 1);
}
private static int saturateLong(long paramLong)
{
int i = (int)paramLong;
return ((paramLong < 0L) ? -2147483648 : (paramLong == i) ? i : 2147483647);
}
private static void print(String paramString, BigDecimal paramBigDecimal)
{
System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n", new Object[] { paramString, Long.valueOf(paramBigDecimal.intCompact), paramBigDecimal.intVal, Integer.valueOf(paramBigDecimal.scale), Integer.valueOf(paramBigDecimal.precision) });
}
private BigDecimal audit()
{
if (this.intCompact == -9223372036854775808L)
{
if (this.intVal == null)
{
print("audit", this);
throw new AssertionError("null intVal");
}
if ((this.precision > 0) && (this.precision != bigDigitLength(this.intVal)))
{
print("audit", this);
throw new AssertionError("precision mismatch");
}
}
else
{
if (this.intVal != null)
{
long l = this.intVal.longValue();
if (l != this.intCompact)
{
print("audit", this);
throw new AssertionError("Inconsistent state, intCompact=" + this.intCompact + "\t intVal=" + l);
}
}
if ((this.precision > 0) && (this.precision != longDigitLength(this.intCompact)))
{
print("audit", this);
throw new AssertionError("precision mismatch");
}
}
return this;
}
static
{
threadLocalStringBuilderHelper = new ThreadLocal()
{
protected BigDecimal.StringBuilderHelper initialValue()
{
return new BigDecimal.StringBuilderHelper();
}
};
zeroThroughTen = new BigDecimal[] { new BigDecimal(BigInteger.ZERO, 0L, 0, 1), new BigDecimal(BigInteger.ONE, 1L, 0, 1), new BigDecimal(BigInteger.valueOf(2L), 2L, 0, 1), new BigDecimal(BigInteger.valueOf(3L), 3L, 0, 1), new BigDecimal(BigInteger.valueOf(4L), 4L, 0, 1), new BigDecimal(BigInteger.valueOf(5L), 5L, 0, 1), new BigDecimal(BigInteger.valueOf(6L), 6L, 0, 1), new BigDecimal(BigInteger.valueOf(7L), 7L, 0, 1), new BigDecimal(BigInteger.valueOf(8L), 8L, 0, 1), new BigDecimal(BigInteger.valueOf(9L), 9L, 0, 1), new BigDecimal(BigInteger.TEN, 10L, 0, 2) };
ZERO_SCALED_BY = new BigDecimal[] { zeroThroughTen[0], new BigDecimal(BigInteger.ZERO, 0L, 1, 1), new BigDecimal(BigInteger.ZERO, 0L, 2, 1), new BigDecimal(BigInteger.ZERO, 0L, 3, 1), new BigDecimal(BigInteger.ZERO, 0L, 4, 1), new BigDecimal(BigInteger.ZERO, 0L, 5, 1), new BigDecimal(BigInteger.ZERO, 0L, 6, 1), new BigDecimal(BigInteger.ZERO, 0L, 7, 1), new BigDecimal(BigInteger.ZERO, 0L, 8, 1), new BigDecimal(BigInteger.ZERO, 0L, 9, 1), new BigDecimal(BigInteger.ZERO, 0L, 10, 1), new BigDecimal(BigInteger.ZERO, 0L, 11, 1), new BigDecimal(BigInteger.ZERO, 0L, 12, 1), new BigDecimal(BigInteger.ZERO, 0L, 13, 1), new BigDecimal(BigInteger.ZERO, 0L, 14, 1), new BigDecimal(BigInteger.ZERO, 0L, 15, 1) };
ZERO = zeroThroughTen[0];
ONE = zeroThroughTen[1];
TEN = zeroThroughTen[10];
LONG_TEN_POWERS_TABLE = new long[] { 1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L, 1000000000L, 10000000000L, 100000000000L, 1000000000000L, 10000000000000L, 100000000000000L, 1000000000000000L, 10000000000000000L, 100000000000000000L, 1000000000000000000L };
BIG_TEN_POWERS_TABLE = new BigInteger[] { BigInteger.ONE, BigInteger.valueOf(10L), BigInteger.valueOf(100L), BigInteger.valueOf(1000L), BigInteger.valueOf(10000L), BigInteger.valueOf(100000L), BigInteger.valueOf(1000000L), BigInteger.valueOf(10000000L), BigInteger.valueOf(100000000L), BigInteger.valueOf(1000000000L), BigInteger.valueOf(10000000000L), BigInteger.valueOf(100000000000L), BigInteger.valueOf(1000000000000L), BigInteger.valueOf(10000000000000L), BigInteger.valueOf(100000000000000L), BigInteger.valueOf(1000000000000000L), BigInteger.valueOf(10000000000000000L), BigInteger.valueOf(100000000000000000L), BigInteger.valueOf(1000000000000000000L) };
BIG_TEN_POWERS_TABLE_INITLEN = BIG_TEN_POWERS_TABLE.length;
BIG_TEN_POWERS_TABLE_MAX = 16 * BIG_TEN_POWERS_TABLE_INITLEN;
THRESHOLDS_TABLE = new long[] { 9223372036854775807L, 922337203685477580L, 92233720368547758L, 9223372036854775L, 922337203685477L, 92233720368547L, 9223372036854L, 922337203685L, 92233720368L, 9223372036L, 922337203L, 92233720L, 9223372L, 922337L, 92233L, 9223L, 922L, 92L, 9L };
}
private static class LongOverflow
{
private static final BigInteger LONGMIN = BigInteger.valueOf(-9223372036854775808L);
private static final BigInteger LONGMAX = BigInteger.valueOf(9223372036854775807L);
public static void check(BigDecimal paramBigDecimal)
{
paramBigDecimal.inflate();
if ((paramBigDecimal.intVal.compareTo(LONGMIN) >= 0) && (paramBigDecimal.intVal.compareTo(LONGMAX) <= 0))
return;
throw new ArithmeticException("Overflow");
}
}
static class StringBuilderHelper
{
final StringBuilder sb = new StringBuilder();
final char[] cmpCharArray = new char[19];
static final char[] DIGIT_TENS;
static final char[] DIGIT_ONES;
StringBuilder getStringBuilder()
{
this.sb.setLength(0);
return this.sb;
}
char[] getCompactCharArray()
{
return this.cmpCharArray;
}
int putIntCompact(long paramLong)
{
assert (paramLong >= 0L);
int j = this.cmpCharArray.length;
int i;
while (paramLong > 2147483647L)
{
long l = paramLong / 100L;
i = (int)(paramLong - (l * 100L));
paramLong = l;
this.cmpCharArray[(--j)] = DIGIT_ONES[i];
this.cmpCharArray[(--j)] = DIGIT_TENS[i];
}
int i1 = (int)paramLong;
while (i1 >= 100)
{
int k = i1 / 100;
i = i1 - (k * 100);
i1 = k;
this.cmpCharArray[(--j)] = DIGIT_ONES[i];
this.cmpCharArray[(--j)] = DIGIT_TENS[i];
}
this.cmpCharArray[(--j)] = DIGIT_ONES[i1];
if (i1 >= 10)
this.cmpCharArray[(--j)] = DIGIT_TENS[i1];
return j;
}
static
{
DIGIT_TENS = new char[] { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9' };
DIGIT_ONES = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
}
}
}