0

0

c++如何判断两个浮点数是否相等_c++精度误差处理【常识】

穿越時空

穿越時空

发布时间:2026-03-16 17:16:01

|

545人浏览过

|

来源于php中文网

原创

应使用容差比较而非==判断浮点数相等,因浮点数是二进制近似表示,直接比较易因微小误差失败;推荐采用相对误差加绝对误差的组合判断方式。

c++如何判断两个浮点数是否相等_c++精度误差处理【常识】

直接用 == 比较两个 floatdouble 几乎总是错的

浮点数在内存中是二进制近似表示,像 0.1 这种十进制小数根本无法精确存储。所以 a == b 看似相等,实际可能差了 1e-16double)或 1e-7float),结果就是 false

常见错误现象:
- 单元测试里 assert(a == 0.3) 失败,尽管你写了 a = 0.1 + 0.2
- 循环里用 for (double x = 0.0; x != 1.0; x += 0.1) 变成死循环
- GUI 滑块值比较、物理引擎碰撞检测失效

  • 永远别用 ==!= 判断浮点数逻辑相等
  • “相等”在浮点语境下只能是“足够接近”,即引入容差(epsilon)
  • 容差不能硬写成固定值(比如 1e-9),得看量级:比较 1e201e20+1 时,1e-9 完全没意义

用相对误差 + 绝对误差组合判断(推荐通用写法)

单一绝对容差(abs(a - b) )在数值很小时有效,但大数时太宽松;单一相对容差(<code>abs(a - b) / max(abs(a), abs(b)) )在接近零时会除零或失真。稳妥做法是两者结合。

实操建议:

  • 定义一个辅助函数,例如:
    bool float_equal(double a, double b, double abs_eps = 1e-9, double rel_eps = 1e-12) {
        double diff = std::abs(a - b);
        double scale = std::max({std::abs(a), std::abs(b), 1.0});
        return diff <= abs_eps || diff <= rel_eps * scale;
    }
  • abs_eps 应对接近零的情况(比如 -1e-101e-11),rel_eps 控制相对精度(通常 1e-12double 足够)
  • 注意 scale 分母取 std::max(..., 1.0) 是为避免 ab 都极小(如 1e-20)时,相对误差被放大到虚假超限
  • 如果明确知道数量级(比如坐标都在 [0, 100]),可简化为纯绝对误差,但需注释说明依据

std::numeric_limits<T>::epsilon() 不是万能容差

std::numeric_limits<double>::epsilon() 返回的是 1.0 附近的单位精度(约 2.2e-16),它**不是**任意两数比较的通用阈值。

阿里妈妈·创意中心
阿里妈妈·创意中心

阿里妈妈营销创意中心

下载

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

  • 它只代表 1.0 和下一个可表示 double 的差值,数值越大,相邻浮点数间距(ULP)也越大
  • 直接写 abs(a - b) 仅在 <code>ab 都接近 1.0 时勉强可用
  • 更安全的用法是:把 epsilon 换算成当前数量级下的 ULP 容差,例如 abs(a - b) —— 这其实就回到了上一节的相对误差思路
  • 某些库(如 Google Test)的 ASSERT_DOUBLE_EQ 内部用的就是带缩放的 epsilon,不是裸 epsilon

特殊值(NaN、Inf)必须显式处理

NaNInf 是浮点标准的一部分,但它们不遵守常规比较规则:NaN == NaNfalseInf == Inftrue,但你很可能不希望 NaN 被当成“相等”混过去。

  • 若业务逻辑中可能出现 NaN(比如未初始化变量、除零、无效数学运算),必须先用 std::isnan() 检查
  • 典型防御写法:
    if (std::isnan(a) || std::isnan(b)) return false; // 或按需抛异常
  • std::isinf() 同理:若允许无穷大且认为 +Inf == +Inf 合理,可保留;否则也应单独判断
  • 很多团队会在调试构建中加断言:assert(!std::isnan(x) && !std::isinf(x)),防止问题扩散

真正麻烦的从来不是怎么写判断,而是忘记检查输入是否合法、没想清楚“相等”在当前业务里到底意味着什么——比如两个向量角度差小于 0.01 弧度算相等,和两个质量值差小于 1e-15 千克算相等,容差来源完全不同。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

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

下载

相关标签:

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

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

597

2024.04.28

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

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

108

2025.10.23

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

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

335

2025.08.29

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

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

108

2025.10.23

chatgpt官网入口地址合集
chatgpt官网入口地址合集

本专题整合了chatgpt官网入口地址、使用教程等内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

minimax入口地址汇总
minimax入口地址汇总

本专题整合了minimax相关入口合集,阅读专题下面的文章了解更多详细地址。

4

2026.03.16

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

7

2026.03.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

114

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

141

2026.03.12

热门下载

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

精品课程

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

共94课时 | 11.5万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22.2万人学习

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

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