版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/strivenoend/article/details/83448271
Bigdecimal解决double/float的精度丢失,使用Bigdecimal类创建BigDecimal实例时,一定用字符串作为构造器的参数,才不会发生精度损失,若使用duoble则依旧会存在精度损失
BigDecimal类源码?
public class BigDecimal extends Number implements Comparable<BigDecimal> {
private final BigInteger intVal;
private final int scale;
private transient int precision;
private transient String stringCache;
static final long INFLATED = Long.MIN_VALUE; private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED);
private static final long serialVersionUID = 6108874887143696463L;
BigDecimal(BigInteger intVal, long val, int scale, int prec) { this.scale = scale; this.precision = prec; this.intCompact = val; this.intVal = intVal; }
public BigDecimal(char[] in, int offset, int len) { this(in,offset,len,MathContext.UNLIMITED); }
public BigDecimal(char[] in) { this(in, 0, in.length); }
public BigDecimal(String val) {//该构造器推荐使用
this(val.toCharArray(), 0, val.length());
}
public BigDecimal(double val) {//不推荐使用该构造器,因为存在一定的不可预知性
this(val,MathContext.UNLIMITED);
}
public BigDecimal(BigInteger val) { scale = 0; intVal = val; intCompact = compactValFor(val); }
public BigDecimal add(BigDecimal augend) {//提供的加法运算 if (this.intCompact != INFLATED) { if ((augend.intCompact != INFLATED)) { return add(this.intCompact, this.scale, augend.intCompact, augend.scale); } else { return add(this.intCompact, this.scale, augend.intVal, augend.scale); } } else { if ((augend.intCompact != INFLATED)) { return add(augend.intCompact, augend.scale, this.intVal, this.scale); } else { return add(this.intVal, this.scale, augend.intVal, augend.scale); } } }
public BigDecimal subtract(BigDecimal subtrahend) {//提供的减法运算 if (this.intCompact != INFLATED) { if ((subtrahend.intCompact != INFLATED)) { return add(this.intCompact, this.scale, -subtrahend.intCompact, subtrahend.scale); } else { return add(this.intCompact, this.scale, subtrahend.intVal.negate(), subtrahend.scale); } } else { if ((subtrahend.intCompact != INFLATED)) { // Pair of subtrahend values given before pair of // values from this BigDecimal to avoid need for // method overloading on the specialized add method return add(-subtrahend.intCompact, subtrahend.scale, this.intVal, this.scale); } else { return add(this.intVal, this.scale, subtrahend.intVal.negate(), subtrahend.scale); } } }
public BigDecimal multiply(BigDecimal multiplicand) {//提供的乘法运算 int productScale = checkScale((long) scale + multiplicand.scale); if (this.intCompact != INFLATED) { if ((multiplicand.intCompact != INFLATED)) { return multiply(this.intCompact, multiplicand.intCompact, productScale); } else { return multiply(this.intCompact, multiplicand.intVal, productScale); } } else { if ((multiplicand.intCompact != INFLATED)) { return multiply(multiplicand.intCompact, this.intVal, productScale); } else { return multiply(this.intVal, multiplicand.intVal, productScale); } } }
public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {//提供的除法运算 return this.divide(divisor, scale, roundingMode.oldMode); }