不能直接用 == 比较两个 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) 或更稳妥的std::abs(a - b)- C++20 起可直接用
std::is_close(需#include),它内部已处理相对/绝对组合逻辑
std::numeric_limits不是万能的“默认容差”::epsilon()
std::numeric_limits返回的是::epsilon() 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。真正难的不是写这十几行,而是想清楚你的数据量级和误差来源——这点常被跳过。
0
0
相关文章
c++中如何使用std::tuple_element_c++获取元组类型信息【详解】
C++ struct和class区别 C++ 默认访问权限与继承方式对比【常识】
C++ shared_ptr怎么用 C++共享智能指针原理与循环引用避坑【智能指针】
C++ priority_queue怎么用 C++优先队列与自定义排序【堆】
如何使用ccache和sccache提升云端c++编译速度? (分布式缓存)
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门AI工具
相关专题
css中float用法
css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。
580
2024.04.28
热门下载
相关下载
最新文章









