1、实际意义
在实际开发中,如果需要进行float或double的精确计算(尤其是财务计算),直接使用float或double是不行的(具体的例子看下边的代码的main方法的测试结果),需要使用BigDecimal。
2、代码

package com.xxx.util; import java.math.BigDecimal; /** * 浮点数精准算法 */ public class BigDecimalArithUtil { private static final int DIV_SCALE = 10;//除法精度(除不尽时保留10为小数) /** 小数精确加法 */ public static double add(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.add(bd2).doubleValue(); } /** 小数精确减法 */ public static double sub(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.subtract(bd2).doubleValue(); } /** 小数精确乘法 */ public static double mul(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); return bd1.multiply(bd2).doubleValue(); } /** 小数精确除法 */ public static double div(double d1,double d2) { BigDecimal bd1 = BigDecimal.valueOf(d1); BigDecimal bd2 = BigDecimal.valueOf(d2); /* * 当除不尽时,以四舍五入的方式(关于除不尽后的值的处理方式有很多种)保留小数点后10位小数 */ return bd1.divide(bd2, DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static void main(String[] args) { //测试加法 System.out.println("0.05+0.01="+BigDecimalArithUtil.add(0.05,0.01)); System.out.println("0.05+0.01="+(0.05+0.01)); //测试减法 System.out.println("1.0-0.42="+BigDecimalArithUtil.sub(1.0,0.42)); System.out.println("1.0-0.42="+(1.0-0.42)); //测试乘法 System.out.println("4.015*100="+BigDecimalArithUtil.mul(4.015,100)); System.out.println("4.015*100="+(4.015*100)); //测试除法 System.out.println("123.3/100="+BigDecimalArithUtil.div(123.3,100)); System.out.println("123.3/100="+(123.3/100)); } }
3、注意点
- 上边的程序我用的是BigDecimal.valueOf(double x)来将double型的x封装成BigDecimal,查看源码如下:
/** * 注意:这通常是将double和float转换为一个BigDecimal的最好方式 */ public static BigDecimal valueOf(double val) { return new BigDecimal(Double.toString(val)); }
在这里直接先将double转换为了String,然后使用如下构造方法再将String转换为BigDecimal
public BigDecimal(String val)
这是最好的做法。如果使用的是直接将double或float转换为BigDecimal的方式,也就是说使用的如下构造器,那么将可能得不到精确结果。(看注释)这一点可以用10.02*10.02来证明。
/** * 注意:The results of this constructor can be somewhat unpredictable. * 该构造器的结果有时是不准确的 */ public BigDecimal(double val)
- 在实际使用中还可能使用int和long来进行浮点数的精确计算(具体做法:将浮点数先乘以相应的倍数转化为int(<=9位十进制数)或long(<=18位十进制数),计算之后再除以之前的倍数,得出结果),而且该种方式的性能会更高,具体的int、long和BigDecimal各自的使用看《Effective Java(第二版)》第48条。
- 需要指出的是,在实际开发中,BigDecimal的性能差的问题基本可以忽略,是浮点数精确计算的首选,而且根据上一条来看,如果将浮点数转化后的整数大于18位的话,也必须用BigDecimal
分类:
Java常用工具类
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞