当前位置:网站首页>使用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的倍数
边栏推荐
- Dynamics 365online applicationuser creation method change
- How to speed up video playback in browser
- 战略合作|SubQuery 成为章鱼网络浏览器的秘密武器
- 其实特简单,教你轻松实现酷炫的数据可视化大屏
- Kubernetes cluster capacity expansion to add node nodes
- 根据热门面试题分析Android事件分发机制(二)---事件冲突分析处理
- Difference between process and thread
- flinkcdc采集oracle在snapshot阶段一直失败,这个得怎么调整啊?
- JS inheritance prototype
- Oracle installation enhancements error
猜你喜欢
What is MD5
如何使用clipboard.js库实现复制剪切功能
H5网页播放器EasyPlayer.js如何实现直播视频实时录像?
Difference between interface iterator and iteratable
Lesson 1: finding the minimum of a matrix
面试被问到了解哪些开发模型?看这一篇就够了
Install pyqt5 and Matplotlib module
【无标题】
js逆向教程第二发-猿人学第一题
Information Security Experiment 1: implementation of DES encryption algorithm
随机推荐
Use 3 in data modeling σ Eliminate outliers for data cleaning
Loxodonframework quick start
沙龙预告|GameFi 领域的瓶颈和解决方案
如何成为一名高级数字 IC 设计工程师(5-2)理论篇:ULP 低功耗设计技术精讲(上)
MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查
信息安全实验二 :使用X-SCANNER扫描工具
Write VBA in Excel, connect to Oracle and query the contents in the database
First issue of JS reverse tutorial
在EXCEL写VBA连接ORACLE并查询数据库中的内容
Difference between process and thread
Netease cloud wechat applet
flink. CDC sqlserver. 可以再次写入sqlserver中么 有连接器的 dem
Unity shader (data type in cghlsl)
Oracle安装增强功能出错
基于智慧城市与储住分离数字家居模式垃圾处理方法
PostgreSQL reports an error when creating a trigger,
Install pyqt5 and Matplotlib module
4、 Fundamentals of machine learning
VSCode+mingw64+cmake
Pick up the premise idea of programming