电话
400 9058 355
不能直接用 == 比较两个 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和三目运算。一个轻量健壮的判断函数长这样: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。真正难的不是写这十几行,而是想清楚你的数据量级和误差来源——这点常被跳过。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...