0

0

如何在Java中判断两个浮点数是否相等_设置误差阈值 (Epsilon)

P粉602998670

P粉602998670

发布时间:2026-02-23 18:31:12

|

200人浏览过

|

来源于php中文网

原创

应使用容差比较而非 == 判断 double 相等,因二进制浮点数无法精确表示多数十进制小数,计算中会产生舍入误差;需根据数值量级选择合适 epsilon,用 math.abs(a - b)

如何在java中判断两个浮点数是否相等_设置误差阈值 (epsilon)

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

Java 中 doublefloat 是二进制浮点数,无法精确表示大多数十进制小数(比如 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) 是最简方案,但有陷阱

这是最常写的写法,但容易忽略边界情况。比如当 ab 是无穷大、NaN,或者两者都极大时,a - b 可能溢出或失去精度。

  • 先检查 Double.isNaN(a) || Double.isNaN(b)NaN 与任何数(包括自己)都不相等
  • 如果 ab 同为 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(因为符号位不同)。

腾讯智影-AI数字人
腾讯智影-AI数字人

基于AI数字人能力,实现7*24小时AI数字人直播带货,低成本实现直播业务快速增增,全天智能在线直播

下载

立即学习Java免费学习笔记(深入)”;

  • Double.equals(a, b)0.0-0.0 返回 false,而数学上它们相等
  • 它不处理 NaN:两个 NaNDouble.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 就藏在看似正常的计算结果里。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

592

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1142

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

371

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

245

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

37

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

114

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.8万人学习

C# 教程
C# 教程

共94课时 | 10万人学习

Java 教程
Java 教程

共578课时 | 70.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号