浮点数运算结果不精确,以及用String来构造BigDecimal进行浮点数精确计算
undefinedundefined
1.浮点数运算结果不精确
先看如下代码
1 System.out.println(1.0 - 0.8); 2 System.out.println(0.2 + 0.1); 3 System.out.println(1.0 - 0.8 == 0.2); //false 4 System.out.println(0.2 + 0.1 == 0.3); //false
输出结果为:
0.19999999999999996
0.30000000000000004
false
false
发现不是我们想要的正确结果,出现了1.0-0.8不等于0.2,0.2+0.1也不等于0.3的现象。
这是因为将java将double浮点数转换为64位二进制性,出现了精度损失。这跟IEEE754标准有关。可参考
https://www.iovi.com/post/2014-07-07-talk-about-double-in-java.html
2.用String来构造BigDecimal做浮点数的精确计算
1 //BigDecimal构造方法参数传入String,精准 2 BigDecimal b2 = new BigDecimal("1.0").subtract(new BigDecimal("0.8")); 3 System.out.println(b2); 4 System.out.println(new BigDecimal("0.1").add(new BigDecimal("0.1")).add(new BigDecimal("0.1"))); 5 System.out.println(b2.equals(new BigDecimal(0.2))); //false 6 System.out.println(b2.equals(new BigDecimal("0.2"))); //true 7 8 BigDecimal t2 = new BigDecimal("0.1"); 9 System.out.println(t2);
输出结果为:
0.2
0.3
false
true
0.1
注意:只有用new BigDecimal(String)的构造方法,得到的才是浮点数的精确值。
以上第5行代码,用0.2这个double类型构造的BigDecimal已经丢失了精度,所以equals结果为false。
用new BigDecimal(Double)的构造方法,构造的BigDecimal不精确。如下:
1 //BigDecimal构造方法参数传入double类型,不精准 2 BigDecimal b = new BigDecimal(1.0).subtract(new BigDecimal(0.8)); 3 System.out.println(b); 4 System.out.println(new BigDecimal(0.1).add(new BigDecimal(0.1)).add(new BigDecimal(0.1))); 5 6 BigDecimal t = new BigDecimal(0.1); 7 System.out.println(t);
输出结果为:
0.1999999999999999555910790149937383830547332763671875
0.3000000000000000166533453693773481063544750213623046875
0.1000000000000000055511151231257827021181583404541015625
参考:
http://superivan.iteye.com/blog/963628
http://blog.csdn.net/xiaoyufu007/article/details/6654010
http://www.cnblogs.com/mingforyou/p/3344489.html
https://www.zhihu.com/question/26994476
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话