C++常见问题精简版"[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
}
  • 是正确的,这意味着等于0的唯一数字是+0-0吗?
  • 在测试零或像|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的建议用途有限。 没有“一刀切”的浮点比较。 您必须考虑变量的语义,可接受的值范围以及计算引入的误差幅度。甚至FAQ也提到了一个警告,说“当x和y的幅度明显大于epsilon,但里程可能会有所不同时”,此功能通常不是问题。

    关于c++ - 比较浮点数为零,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19837576/

    10-12 04:33