如何在Java中比较两个浮点数是否相等_设置精度阈值(Epsilon)的方法

夏枫君_1162

夏枫君_1162

2026-03-18

567人浏览

原创

应使用容差值 epsilon 判断 double 相等,因浮点数二进制无法精确表示十进制小数(如 0.1+0.2≠0.3),== 比较会因精度误差返回 false,Double.compare 也无法解决精度问题。

如何在java中比较两个浮点数是否相等_设置精度阈值(epsilon)的方法

Java里直接用 == 比较两个 double 会出错

浮点数在二进制中无法精确表示大多数十进制小数,比如 0.1 + 0.2 的结果不是 0.3,而是 0.30000000000000004。所以用 == 判断相等大概率失败,哪怕肉眼看起来一样。

常见错误现象:0.1 + 0.2 == 0.3 返回 false;单元测试里断言 assertEquals(expected, actual) 报错但数值打印出来“明明一样”。

  • 永远别对 float 或 double 用 == 做逻辑相等判断
  • 连 Double.compare(a, b) == 0 都不行——它比较的是 IEEE 754 位模式,仍会把 0.0 和 -0.0 当作不同,且不解决精度误差问题
  • 需要自己定义“多近才算相等”,也就是引入一个极小的容差值 epsilon

用 Math.abs(a - b) 是最常用做法

这是手动实现浮点数“近似相等”的核心逻辑:计算两数之差的绝对值,看是否落在可接受误差范围内。

使用场景:写工具方法、单元测试断言、业务逻辑中需判断计算结果是否落在预期区间(如物理模拟、金融四舍五入前校验)。

  • epsilon 不是越小越好——设成 1e-17 可能比 double 的最低有效位还小,反而没意义
  • 典型取值:1e-6(适合一般工程计算),1e-9(高精度需求),1e-15(接近 double 机器精度极限)
  • 注意:如果 a 或 b 是极大值(如 1e308),相对误差更合理,此时应改用 Math.abs(a - b)

简单示例:

public static boolean equals(double a, double b, double epsilon) {
    return Math.abs(a - b) <h3>JUnit 5 的 <code>Assertions.assertEquals(double, double, double)</code> 就是封装了这个逻辑</h3><p>写测试时别自己手写容差判断,直接用框架提供的重载方法,语义清晰且自带报错信息。</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9868" title="Java注释规范Skills"><img
														src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Java注释规范Skills" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill9868" title="Java注释规范Skills" class="overflowclass">Java注释规范Skills</a>
													<p class="overflowclass">当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill9868" title="Java注释规范Skills" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div><p>参数差异:<code>assertEquals(expected, actual, epsilon)</code> —— 第三个参数是最大允许误差,不是百分比,也不是相对误差。</p>
  • 如果漏传第三个参数,调用的是 assertEquals(double, double),它内部用的是 Double.compare,**仍然会出错**
  • JUnit 4 用的是 assertEquals(double, double, double),签名一致,但底层实现略有不同(不影响使用)
  • 注意:这个方法对 NaN 的处理是——只要任一参数为 NaN,就返回 false(符合 IEEE 754 规范)

别忽略 Float 和 Double 的静态方法 isFinite 和 isNaN

真实业务中,参与比较的浮点数可能来自外部输入、解析失败或计算溢出,出现 NaN、Infinity 或 -Infinity。这时候直接套用 Math.abs(a - b) 会得到意外结果。

例如:Math.abs(Double.NaN - 1.0) 是 NaN,而 NaN 永远为 false,但你可能希望它抛异常或明确返回 false。

  • 建议在比较前加校验:if (!Double.isFinite(a) || !Double.isFinite(b)) return false;
  • Double.isNaN(x) 比 x != x 更可读,也更安全(后者在某些 JIT 优化下可能被误判)
  • 如果业务允许 Infinity == Infinity,需单独判断:Double.isInfinite(a) && Double.isInfinite(b) && Math.signum(a) == Math.signum(b)

精度阈值本身不是魔法数字,它得和你的数据量级、计算路径长度、硬件平台都挂钩。同一个 epsilon 在单次加法和迭代 1000 次的累加器里,意义完全不同。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11597

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8722

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7492

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1224

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

988

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1476

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3049

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20311

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1335

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习