当前位置:网站首页>使用BigDecimal的坑
使用BigDecimal的坑
2022-07-07 07:10:00 【Keeling1720】
BigDecimal的坑
BigDecimal常被我们用于计算一些需要精确计算的场景,例如金额的计算。但是,BigDecimal也有很多不为人知的坑。下面,我们就来简单介绍几个常见的坑。
1、使用valueOf() 替代new BigDecimal
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal(0.01);
BigDecimal bigDecimal2 = BigDecimal.valueOf(0.01);
System.out.println(bigDecimal1);
System.out.println(bigDecimal2);
}
输出结果是:
可以看到,直接new BigDecimal传入0.01的时候,由于0.01这个数字计算机是无法精确表示的,导致传入到BigDecimal中就已经丢失精度。最终输出的结果就有存在误差。而valueOf 则不同,他的底层将Double转化为了String,确保了他的精度不会丢失。
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
总结:尽量使用字符串形式来构造BigDecimal对象,如果实在不行,那么也请使用BigDecimal.valueOf()方法将值进行转换,以此确保我们的精度。
2、使用compareTo而不是equals进行比较
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal("1.0");
BigDecimal bigDecimal2 = new BigDecimal("1.00");
System.out.println(bigDecimal2.equals(bigDecimal1));
System.out.println(bigDecimal2.compareTo(bigDecimal1));
}
运行结果:
运行结果中,使用equals对比两个BigDecimal的值会等于false,因为BigDecimal的equals会比较两个数字的精度,而compareTo方法只会比较两个数的大小。
总结:使用compareTo而不是equals比较两个BigDecimal的值。
3、BigDecimal并不是无限精度
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal("1.0");
BigDecimal bigDecimal2 = new BigDecimal("3.0");
bigDecimal1.divide(bigDecimal2);
}
运行结果如下:
这是因为,1 / 3 等于 无限循环小数(0.33333… )。这个时候,我们就必须告诉JVM,我们不需要最精确的结果。修改代码为:
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal("1.0");
BigDecimal bigDecimal2 = new BigDecimal("3.0");
System.out.println(bigDecimal1.divide(bigDecimal2, RoundingMode.HALF_UP));
}
运行结果:
4、转化为String要用对方法
public static void main(String[] args) {
BigDecimal bigDecimal = BigDecimal.valueOf(12345678902132123113213.12345678912345678);
//必要时,使用科学计数法
System.out.println(bigDecimal.toString());
//不使用科学计数法
System.out.println(bigDecimal.toPlainString());
//工程计算中经常使用的记录数字的方法,类似科学计数法,但要求是10的幂必须是3的倍数
System.out.println(bigDecimal.toEngineeringString());
}
运行结果:
总结:
- toString():如果必要的时候,使用科学计数法。
- toPlainString():不使用科学计数法
- toEngineeringString():工程计算中经常使用的记录数字的方法,类似科学计数法,但要求是10的幂必须是3的倍数
边栏推荐
- VSCode+mingw64+cmake
- 基础篇:带你从头到尾玩转注解
- Schema-validation: wrong column type encountered in column XXX in table XXX
- 网易云微信小程序
- Communication mode between processes
- Upload taro pictures to Base64
- golang select机制和超时问题怎么解决
- Install pyqt5 and Matplotlib module
- 有没有大佬帮忙看看这个报错,有啥排查思路,oracle cdc 2.2.1 flink 1.14.4
- flinkcdc采集oracle在snapshot阶段一直失败,这个得怎么调整啊?
猜你喜欢
H5 web player easyplayer How does JS realize live video real-time recording?
Loxodonframework quick start
[4G/5G/6G专题基础-147]: 6G总体愿景与潜在关键技术白皮书解读-2-6G发展的宏观驱动力
NATAPP内网穿透
VSCode+mingw64
Netease cloud wechat applet
Unity shader (to achieve a simple material effect with adjustable color attributes only)
4、 Fundamentals of machine learning
flex弹性布局
Over 100000 words_ Ultra detailed SSM integration practice_ Manually implement permission management
随机推荐
剑指 Offer II 107. 矩阵中的距离
La différence entre viewpager 2 et viewpager et la mise en œuvre de la rotation viewpager 2
scrapy爬虫mysql,Django等
JS reverse tutorial second issue - Ape anthropology first question
[4g/5g/6g topic foundation-146]: Interpretation of white paper on 6G overall vision and potential key technologies-1-overall vision
Octopus future star won a reward of 250000 US dollars | Octopus accelerator 2022 summer entrepreneurship camp came to a successful conclusion
asp. How to call vb DLL function in net project
基础篇:带你从头到尾玩转注解
sqlplus乱码问题,求解答
信息安全实验一:DES加密算法的实现
CDZSC_2022寒假个人训练赛21级(2)
Information Security Experiment 2: using x-scanner scanning tool
IIS faked death this morning, various troubleshooting, has been solved
Information Security Experiment 4: implementation of IP packet monitoring program
ComputeShader
Unity shader (data type in cghlsl)
网易云微信小程序
Unity3d interface is embedded in WPF interface (mouse and keyboard can respond normally)
Unity shader (to achieve a simple material effect with adjustable color attributes only)
Elaborate on MySQL mvcc multi version control