当前位置:网站首页>使用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的倍数
边栏推荐
- 20排位赛3
- The configuration and options of save actions are explained in detail, and you won't be confused after reading it
- Colorbar of using vertexehelper to customize controls (II)
- 如何成为一名高级数字 IC 设计工程师(5-2)理论篇:ULP 低功耗设计技术精讲(上)
- ViewPager2和VIewPager的区别以及ViewPager2实现轮播图
- sql 里面使用中文字符判断有问题,哪位遇到过?比如value<>`无`
- 2020浙江省赛
- Niuke - Huawei question bank (61~70)
- Unity shader (pass user data to shader)
- Arthas simple instructions
猜你喜欢
Esp8266 uses TF card and reads and writes data (based on Arduino)
PLC信号处理系列之开关量信号防抖FB
Unity shader (basic concept)
Mysql:select ... for update
如何使用clipboard.js库实现复制剪切功能
In fact, it's very simple. It teaches you to easily realize the cool data visualization big screen
[Frida practice] "one line" code teaches you to obtain all Lua scripts in wegame platform
ComputeShader
Diffusion模型详解
Unity shader (learn more about vertex fragment shaders)
随机推荐
HCIP 第一天 笔记整理
MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查
How to become a senior digital IC Design Engineer (5-3) theory: ULP low power design technology (Part 2)
Strategic cooperation subquery becomes the secret weapon of Octopus web browser
asp. How to call vb DLL function in net project
20排位赛3
消费互联网的产业链其实是很短的,它仅仅承接平台上下游的对接和撮合的角色
Difference between interface iterator and iteratable
有没有大佬帮忙看看这个报错,有啥排查思路,oracle cdc 2.2.1 flink 1.14.4
4、 Fundamentals of machine learning
Detailed explanation of diffusion model
NETCORE 3.1 solves cross domain problems
如何成为一名高级数字 IC 设计工程师(5-3)理论篇:ULP 低功耗设计技术精讲(下)
JS reverse tutorial second issue - Ape anthropology first question
Lesson 1: finding the minimum of a matrix
面试被问到了解哪些开发模型?看这一篇就够了
[bw16 application] Anxin can realize mqtt communication with bw16 module / development board at instruction
How to speed up video playback in browser
Pick up the premise idea of programming
Database multi table Association query problem