欢迎来到陷阱、圈套和漏洞的世界。如其他地方所述,不存在用于浮点相等和容差的通用解决方案。鉴于此,程序员可以在特定情况下使用一些工具和公理。
fabs(a_float - b_float) < tol
有提到的缺点 OP:“对于 a_float 可能非常小或可能非常大的一般情况,效果不佳。” fabs(a_float - ref_float) <= fabs(ref_float * tol)
更好地应对变体范围。
OP 的“单精度浮点数使用 tol = 10E-6”对于 C 和 C++ 来说有点令人担忧,因此很容易float
将算术提升到double
,然后它的“容差” double
,而不是float
,发挥作用。考虑到float f = 1.0; printf("%.20f\n", f/7.0);
这么多新程序员没有意识到7.0
导致了double
精度计算。建议使用double
您的代码,除非大量数据需要float
较小的大小。
C99 提供nextafter()
了有助于衡量“公差”的有用信息。使用它,可以确定下一个可表示的数字。这将有助于 OP“......存储类型的有效数字的全部数量减去一......以允许舍入错误。” if ((nextafter(x, -INF) <= y && (y <= nextafter(x, +INF))) ...
使用的那种或tol
“宽容”往往是问题的症结所在。大多数情况下(恕我直言)相对公差很重要。例如“x 和 y 是否在 0.0001% 之内”?有时需要绝对公差。例如“x 和 y 是否在 0.0001 范围内”?
公差的值通常是有争议的,因为最佳值通常取决于情况。0.01 以内的比较可能适用于美元的财务申请,但不适用于日元。(提示:一定要使用易于更新的编码风格。)