BigDecimal精度问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
BigDecimal精度问题
介绍
1.商业计算使⽤BigDecimal。
2.使⽤参数为String的构造函数。
3.BigDecimal都是不可变的,每⼀步的运算时,都会产⽣⼀个新的对象。
所以在做加减乘除后千万要保存操作后的值。
案例
代码1:
public class Test001 {
public static void main(String args[]) {
BigDecimal a = new BigDecimal(1.5);
BigDecimal a1 = new BigDecimal(329.530);
System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
输出:
494.29
代码2:
public class Test001 {
public static void main(String args[]) {
BigDecimal a = new BigDecimal("1.5");
BigDecimal a1 = new BigDecimal("329.530");
System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
输出:
494.30
计算器输出结果:
489.30
原因解析:
JDK的描述:参数为dubbo的构造⽅法的结果具有⼀定的不可预知性,认为java在写⼊new BigDecimal(0.1)中这个0.1不是标准的0.1可能是⼀个⽆限趋近于0.1的⼀个⼩数,虽然表⾯上等于他。
源码
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);
}
}
}
在这个地⽅就是判断是不是字符串的,这个this.intCompact 是获取到参数的整数值,如果获取到时⼀⼤串数字,那就是dubbo参数传进来的,这⾥进⾏判断,从⽽获取到不同的值。
进⼊到不同的⽅法进⾏运算。
其实运算原理⼤致说下,⼩数转换为整数计算,最后除以10的n次⽅即可。