概述
1. 什么是BigDecimal?
在Java中,BigDecimal是一个基础的数据结构,它常常用于需要高精度计算的应用场景,比如表示一个商品的价格、或者是计算商品的购买价格中都经常用到BigDecimal,因为这些数值要求高精度,如果我们使用的是Double、Float等数据类型在一定场景下会导致数值出现一些误差。比如现在有一下代码:
public class BigDecimalAnalyze {
public static void main(String[] args) {
double price1=20.15;
float price2=40.10F;
BigDecimal bigDecimal1=new BigDecimal(price1);
BigDecimal bigDecimal2=new BigDecimal(price2);
//输出实际值
System.out.println(bigDecimal1);
System.out.println(bigDecimal2);
}
}
//控制台输出
20.14999999999999857891452847979962825775146484375
40.09999847412109375
从以上结果中可以分析出,double、float类型表示的数值比原始值稍微偏小一些,虽然现在感觉差的不是特别多,但是万一到时候订单到达比如100W的时候,所差的金额就特别多了,这在实际项目中肯定是不允许的,如果使用BigDecimal计算就能避免以上问题。
2. BigDecimal有哪几种构造方法式?
通过查看源码可以分析出BigDecimal共有以上17中构造方法,但是如果涉及到金额的计算建议使用String入参进行构造。
3. BigDecimal的简单使用
在实际项目中使用的比较多的就是BigDecimal的运算,比如常规的加、减、乘、除、取余等。
3.1 BigDecimal
加法运算底层实现方法:
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);
}
}
}
private static BigDecimal add(BigInteger fst, int scale1, BigInteger snd, int scale2) {
//保留多少位小数
int rscale = scale1;
long sdiff = (long)rscale - scale2;
//判断是否需要保留小数
if (sdiff != 0) {
if (sdiff < 0) {
int raise = checkScale(fst,-sdiff);
rscale = scale2;
fst = bigMultiplyPowerTen(fst,raise);
} else {
int raise = checkScale(snd,sdiff);
snd = bigMultiplyPowerTen(snd,raise);
}
}
BigInteger sum = fst.add(snd);
return (fst.signum == snd.signum) ?
new BigDecimal(sum, INFLATED, rscale, 0) :
valueOf(sum, rscale, 0);
}
从以上源码中,可以简单的发现最终结果还是会返回一个新的BigDecimal对象,当然具体实现不止以上列出来的一个。
//加法运算
BigDecimal result1 = bigDecimal1.add(bigDecimal2);
System.out.println("未进行舍入操作的结果:"+result1);
//四舍五入运算
result1 = result1.setScale(2, BigDecimal.ROUND_HALF_DOWN);
System.out.println("结果四舍五入:"+result1);
//使用String类型作为入参
BigDecimal price3=new BigDecimal("20.15");
BigDecimal price4=new BigDecimal("40.10");
//进行加法运算
BigDecimal result2=price3.add(price4);
System.out.println("字符串入参未做任何处理的结果"+result2);
//控制台打印的结果
未进行舍入操作的结果:60.24999847412109232891452847979962825775146484375
结果四色五入:60.25
字符串入参未做任何处理的结果60.25
从以上代码中可以分析出,通过BigDecimal的底层方法可以实现结果舍入操作,这里需要注意的是,通过String入参构造的BigDecimal运算出来的结果不需要多于的舍入操作。
3.2 BigDecimal减法操作
//减法运算
BigDecimal result3=bigDecimal1.subtract(bigDecimal2);
System.out.println("未做处理的减法操作:"+result3);
BigDecimal result4=result3.setScale(2,BigDecimal.ROUND_HALF_DOWN);
System.out.println("进行了四舍五入的减法操作:"+result4);
BigDecimal result5=price3.subtract(price4);
System.out.println("字符串减法运算:"+result5);
//控制台打印结果
未做处理的减法操作:-19.94999847412109517108547152020037174224853515625
进行了四舍五入的减法操作:-19.95
字符串减法运算:-19.95
BigDecimal中乘法操作使用multiply()
方法、除法操作使用divide()
方法操作、取余使用divideAndRemainder()
方法。
最后
以上就是纯真冰淇淋为你收集整理的【源码解析】-- BigDecimal源码简要分析以及简单使用的全部内容,希望文章能够帮你解决【源码解析】-- BigDecimal源码简要分析以及简单使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复