应使用容差比较而非 == 判断 double 相等,因二进制浮点数无法精确表示多数十进制小数,计算中会产生舍入误差;需根据数值量级选择合适 epsilon,用 math.abs(a - b)
直接用 == 比较两个
double会出错Java 中
double和float是二进制浮点数,无法精确表示大多数十进制小数(比如0.1),计算过程还会累积舍入误差。所以a == b在绝大多数浮点运算后都会返回false,哪怕数学上它们“应该相等”。常见错误现象:
–0.1 + 0.2 == 0.3返回false
– 循环累加0.1十次后与1.0比较失败
– 单元测试里断言assertEquals(expected, actual)报错,但数值看起来一样
- 永远不要对
double/float使用==判断逻辑相等- 必须引入一个极小的容差值(epsilon),判断差值是否落在这个范围内
- epsilon 不是固定写死
1e-6就万事大吉——它得和你要比较的数值量级匹配
Math.abs(a - b) 是最简方案,但有陷阱这是最常写的写法,但容易忽略边界情况。比如当
a或b是无穷大、NaN,或者两者都极大时,a - b可能溢出或失去精度。
- 先检查
Double.isNaN(a) || Double.isNaN(b),NaN与任何数(包括自己)都不相等- 如果
a和b同为Double.POSITIVE_INFINITY或同为Double.NEGATIVE_INFINITY,可直接认为相等- 普通场景下用
Math.abs(a - b) 没问题,但 epsilon 要选对:比较 <code>1e-10级别的数,用1e-6就太大;比较1e9级别的数,用1e-6又太小- 推荐用相对误差:比如
Math.abs(a - b) ,但要注意分母为 0 的情况用
Double.compare()或Double.equals()?别被名字骗了这两个方法不是为“近似相等”设计的:
Double.compare(a, b)比较的是 IEEE 754 规范下的精确序关系;Double.equals()内部调用的是doubleToLongBits()的位比较,连-0.0 == 0.0都返回false(因为符号位不同)。立即学习“Java免费学习笔记(深入)”;
Double.equals(a, b)对0.0和-0.0返回false,而数学上它们相等- 它不处理
NaN:两个NaN的Double.equals()返回false(符合规范,但不符合业务直觉)- 它完全无视误差——和
==一样脆弱- 除非你明确要比较 bit pattern(比如序列化校验),否则别用它们做“值相等”判断
JUnit 5 的
Assertions.assertEquals(double expected, double actual, double epsilon)这是最贴近实际开发的用法。单元测试里几乎不需要手写误差逻辑,JUnit 已封装好健壮实现。
- 第三个参数就是 epsilon,必须显式传入,没有默认值
- 它内部做了
NaN和无穷大的安全判断,比手写更可靠- 注意:这个重载只存在于
org.junit.jupiter.api.Assertions,老版 JUnit 4 的Assert.assertEquals(double, double, double)行为类似,但 JUnit 5 更推荐用新 API- 示例:
Assertions.assertEquals(0.3, 0.1 + 0.2, 1e-10);—— 这行能过,而不用epsilon的版本必挂真正难的不是写那行
Math.abs(a - b) ,而是想清楚 eps 该取多大、要不要考虑数量级、要不要兼容 <code>NaN和无穷大。这些细节一旦漏掉,bug 就藏在看似正常的计算结果里。
0
0
相关文章
如何在Java中使用内部类实现简单的多继承效果
详解Java集合中的延迟加载策略_理解某些集合在首次添加时才创建数组
什么是Java中的虚方法(Virtual Method)_Java中所有普通方法的本质
在Java里如何使用File类编写文件操作系统_Java文件输入输出操作解析
什么是Java中的方法重写 (Override) 与隐藏 (Hiding)_实例与静态的差异
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门AI工具
相关专题
css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。
592
2024.04.28
本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。
1044
2026.02.13
本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。
334
2026.02.13
本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。
213
2026.02.13
本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。
35
2026.02.13
本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。
111
2026.02.13
热门下载
相关下载
最新文章




