不能直接用 == 比较两个 float 或 double,因为浮点数以二进制近似存储(如 0.1 + 0.2 ≠ 0.3),导致精度误差;应使用 std::abs(a - b)
为什么不能直接用
==比较两个float或double因为浮点数在内存中是二进制近似表示,像
0.1 + 0.2实际存储的值并不是精确的0.3,而是类似0.30000000000000004。直接用==判断会返回false,即使数学上相等。用
std::abs(a - b) 是最常用方法核心思路是判断两数之差是否落在可接受的误差范围内。关键在于选对
epsilon值:
- 对绝对值较小的数(比如接近 0),用固定小值如
1e-9(float)或1e-15(double)通常够用- 对较大数值(比如
1e10),固定epsilon会失效——此时应改用相对误差:std::abs(a - b) 或更稳妥的 <code>std::abs(a - b)- C++20 起可直接用
std::is_close(需#include <cmath></cmath>),它内部已处理相对/绝对组合逻辑
std::numeric_limits<t>::epsilon()</t>不是万能的“默认容差”
std::numeric_limits<double>::epsilon()</double>返回的是1.0和下一个可表示double的差值(约2.22e-16),它只适用于与1.0同量级的数。直接拿它当通用epsilon用,会导致:
- 比较
1e8级别的数时,容差太小,本该相等的数被判为不等- 比较接近
0的数(如1e-20)时,a * epsilon可能下溢成0,退化为纯绝对误差判断,但此时epsilon()又太大- 它不处理
NaN、inf等特殊值,需额外检查实际写法建议:优先封装函数,兼顾边界与可读性
别每次手写一堆
std::abs和三目运算。一个轻量健壮的判断函数长这样:立即学习“C++免费学习笔记(深入)”;
bool nearly_equal(double a, double b, double abs_tol = 1e-9, double rel_tol = 1e-12) { if (a == b) return true; // 处理完全相等、inf == inf、-0 == +0 if (std::isnan(a) || std::isnan(b)) return false; double diff = std::abs(a - b); return diff <= std::max({abs_tol, rel_tol * std::max(std::abs(a), std::abs(b))}); }调用时按场景传参:
nearly_equal(x, y)默认精度足够日常;涉及科学计算可显式加大rel_tol;对亚微米级物理量则收紧abs_tol。真正难的不是写这十几行,而是想清楚你的数据量级和误差来源——这点常被跳过。
相关文章
相关标签:
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门AI工具
相关专题
css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。
7127
2024.04.28
Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。
80
2026.10.28
Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。
60
2026.10.28
Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。
200
2026.10.28
本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。
140
2026.10.22
本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。
120
2026.10.22
热门下载
相关下载
精品课程
最新文章












