c++ - 将 float 与零进行比较

标签 c++ floating-point

C++ FAQ 精简版 "[29.17] Why doesn't my floating-point comparison work?"推荐这个平等测试:

#include <cmath>  /* for std::abs(double) */

inline bool isEqual(double x, double y)
{
  const double epsilon = /* some small number such as 1e-5 */;
  return std::abs(x - y) <= epsilon * std::abs(x);
  // see Knuth section 4.2.2 pages 217-218
}
  1. 这是否正确,这意味着唯一等于零的数字是 +0-0 ?
  2. 在测试零或者更确切地说是像 |x| < epsilon 这样的测试时,是否也应该使用此功能? ?

更新

正如 Daniel Daranas 所指出的,该函数最好称为 isNearlyEqual。 (这是我关心的情况)。

有人指出"Comparing Floating Point Numbers" ,我想更突出地分享。

最佳答案

您的观察是正确的。

如果 x == 0.0 ,然后 abs(x) * epsilon为零,您正在测试是否 abs(y) <= 0.0 .

如果 y == 0.0那么你正在测试 abs(x) <= abs(x) * epsilon这意味着 epsilon >= 1 (不是)或x == 0.0 .

所以is_equal(val, 0.0)is_equal(0.0, val)没有意义,你可以说val == 0.0 .如果您只想完全接受 +0.0-0.0 .

在这种情况下,FAQ 的建议是有限的。 没有“一刀切”的浮点比较。您必须考虑变量的语义、可接受的值范围以及计算引入的误差幅度。甚至常见问题解答都提到了一个警告,说这个函数通常不是问题“当 x 和 y 的大小明显大于 epsilon 时,但你的里程可能会有所不同”。

关于c++ - 将 float 与零进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19837576/

相关文章:

c++ - 在 VS2019 或 VSCode 中使用 Unreal Engine 4.24.2 时,如何修复这些错误的 Intellisense 错误?

c++ - 无法打印所有整数值

c# - 如何将 COleDateTime 对象列表作为 SAFEARRAY* 传递

c++ - QPixmap 将正方形的内容复制到另一个图像中

performance - 现实世界中的 CPU 是否不使用 IEEE 754?

c++ - 将逗号分隔的数据分配给 vector

math - 为什么GNU科学库的trig.c文件中的PI要分为三部分?

c++ - float128 和 double-double 运算

regex - 如何在正则表达式中添加用户定义的字符串

c++ - 浮点分辨率似乎比它应该的更受限制