BigDecimal 使用总结
工作中很多情况下需要进行精确的小数运算,,在 Java 中使用 float 和 double 这两种浮点数类型进行小数运算时,往往很难达到令人满意的效果,小数点后面总是存在很多位的小数,看起来令人费解,因此不推荐使用这两种浮点数类型进行小数运算。BigDecimal 就是专门用来进行精确计算的,使用起来也非常方便,下面我们就通过代码一起看一下吧。
一、运算效果对比
先给出代码和运算结果,然后再进行结论总结。
package com.jobs; import java.math.BigDecimal; public class Demo1 { public static void main(String[] args) { double f1 = 0.1; double f2 = 0.2; double result1 = f1 + f2; System.out.println("Double相加的结果:" ); System.out.println(result1); System.out.println("-----------------"); //使用浮点数初始化BigDecimal BigDecimal bd1 = new BigDecimal(0.1); BigDecimal bd2 = new BigDecimal(0.2); BigDecimal result2 = bd1.add(bd2); System.out.println("浮点数初始化的BigDecimal相加的结果:"); System.out.println(result2); System.out.println("-----------------"); BigDecimal bd3 = new BigDecimal("0.1"); BigDecimal bd4 = new BigDecimal("0.2"); BigDecimal result3 = bd3.add(bd4); System.out.println("字符串初始化的BigDecimal相加的结果:"); System.out.println(result3); } }
执行的结果是:
从上面的执行结果,可以看出:
【double 类型的小数】和【使用浮点数初始化的 BigDecimal 】在进行小数运算后,结果并不是我们所期望的,甚至【使用浮点数初始化的 BigDecimal 小数】进行小数运算的结果,更加令人感到不爽。
【使用字符串初始化的 BigDecimal 】进行小数运算后的结果,是我们所期望的结果,因此后续尽量使用字符串来初始化 BigDecimal 。
二、BigDecimal 运算示例
还是先给出代码,再总结结论吧:
package com.jobs; import java.math.BigDecimal; import java.math.RoundingMode; public class Demo2 { public static void main(String[] args) { BigDecimal bd1 = new BigDecimal("10"); BigDecimal bd2 = new BigDecimal("3"); //相加 BigDecimal add = bd1.add(bd2); System.out.println("10/3 相加的结果:" + add); //相减 BigDecimal subtract = bd1.subtract(bd2); System.out.println("10/3 相减的结果:" + subtract); //相乘 BigDecimal multiply = bd1.multiply(bd2); System.out.println("10/3 相乘的结果:" + multiply); //相除(如果能够除尽,则一切正常) BigDecimal divide = bd2.divide(bd1); System.out.println("3/10 相除的结果:" + divide); //相除(如果除不尽,则抛异常) //原因:BigDecimal属于精确计算,如果除不尽,必须指定舍入规则 BigDecimal divide0 = bd1.divide(bd2); System.out.println("10/3 相除的结果:" + divide0); } }
执行的结果是:
从执行的结果,可以看出:
【使用字符串初始化的 BigDecimal 】在进行除法运算时,如果能够除尽的话,代码运行就正常,如果除不尽的话,就会抛出异常。原因就是 BigDecimal 属于精确运算,如果除不尽的话,必须要指定小数的舍入规则,这样才能确保运算的结果是我们预期的结果。
三、常用的小数舍入规则
系统提供了很多小数舍入规则,我们常用的也就是 3 种舍入规则:
- RoundingMode.UP 进一法
- RoundingMode.FLOOR 去尾法
- RoundingMode.HALF_UP 四舍五入
package com.jobs; import java.math.BigDecimal; import java.math.RoundingMode; public class Demo2 { public static void main(String[] args) { BigDecimal bd1 = new BigDecimal("10"); BigDecimal bd2 = new BigDecimal("3"); //常用的三个舍入规则为: //RoundingMode.UP 进一法 //RoundingMode.FLOOR 去尾法 //RoundingMode.HALF_UP 四舍五入 System.out.println("相除精确2位小数:"); BigDecimal divide1 = bd1.divide(bd2, 2, RoundingMode.UP); System.out.println("10/3 小数第3位进1的结果:" + divide1); BigDecimal divide2 = bd1.divide(bd2, 2, RoundingMode.FLOOR); System.out.println("10/3 小数第3位舍去的结果:" + divide2); BigDecimal divide3 = bd1.divide(bd2, 2, RoundingMode.HALF_UP); System.out.println("10/3 小数第3位四舍五入的结果:" + divide3); BigDecimal bd3 = new BigDecimal("0.1"); BigDecimal bd4 = new BigDecimal("4"); BigDecimal divide4 = bd3.divide(bd4, 2, RoundingMode.HALF_UP); System.out.println("0.1/4 实际结果是 0.025,小数第3位四舍五入的结果:" + divide4); } }
执行结果如下:
以上就是三种舍入规则的效果演示,平时使用最多的应该还是四舍五入。我们在使用 BigDecimal 进行除法运算时,尽量指定要保留的小数位数,以及舍入规则,否则就会有除不尽导致代码执行过程中抛异常的风险。
Ok,到此为止,有关 BigDecimal 的基本使用,已经介绍的差不多了,相关的示例代码下载地址如下:
https://files.cnblogs.com/files/blogs/699532/BigDecimalDemo.zip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2022-01-17 Java 网络编程技术总结