当前位置:网站首页>使用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的倍数
边栏推荐
- CSDN salary increase technology - learn about the use of several common logic controllers of JMeter
- 第一讲:包含min函数的栈
- Unity shader (pass user data to shader)
- 如何成为一名高级数字 IC 设计工程师(5-2)理论篇:ULP 低功耗设计技术精讲(上)
- 牛客网——华为题库(61~70)
- 沙龙预告|GameFi 领域的瓶颈和解决方案
- golang select机制和超时问题怎么解决
- [Frida practice] "one line" code teaches you to obtain all Lua scripts in wegame platform
- Netease cloud wechat applet
- Strategic cooperation subquery becomes the secret weapon of Octopus web browser
猜你喜欢
JS reverse tutorial second issue - Ape anthropology first question
flex弹性布局
Information Security Experiment 3: the use of PGP email encryption software
H5网页播放器EasyPlayer.js如何实现直播视频实时录像?
【frida实战】“一行”代码教你获取WeGame平台中所有的lua脚本
Impression notes finally support the default markdown preview mode
信息安全实验二 :使用X-SCANNER扫描工具
[4G/5G/6G专题基础-146]: 6G总体愿景与潜在关键技术白皮书解读-1-总体愿景
小程序弹出半角遮罩层
Use 3 in data modeling σ Eliminate outliers for data cleaning
随机推荐
如何成为一名高级数字 IC 设计工程师(5-2)理论篇:ULP 低功耗设计技术精讲(上)
How to become a senior digital IC Design Engineer (5-3) theory: ULP low power design technology (Part 2)
【原创】程序员团队管理的核心是什么?
细说Mysql MVCC多版本控制
Elaborate on MySQL mvcc multi version control
VSCode+mingw64+cmake
(3/8) method parameters of improper use of enumeration (2)
12、 Sort
golang select机制和超时问题怎么解决
ComputeShader
Upload taro pictures to Base64
csdn涨薪技术-浅学Jmeter的几个常用的逻辑控制器使用
Unity shader (learn more about vertex fragment shaders)
小程序弹出半角遮罩层
第一讲:包含min函数的栈
请教个问题,我用sql-client起了个同步任务,从MySQL同步到ADB,历史数据有正常同步过去
**grafana安装**
Unity shader (data type in cghlsl)
Network request process
NATAPP内网穿透