一般单元测试中的浮点数比较

Floating point comparison in general unit tests

我知道这个问题已经讨论了很多。我在网上搜索并自己想出了一个算法。我想知道它是否可以作为在一般单元测试(而不是一些 serious/professional 数字测试)中正常工作的默认实现。

bool equal_to(double x, double y) {
  using limits = std::numeric_limits<double>;
  auto mag_x = std::abs(x);
  auto mag_y = std::abs(y);
  if (mag_x < mag_y) {
    std::swap(x, y);
    std::swap(mag_x, mag_y);
  }
  auto eps = limits::epsilon() * mag_x;
  auto lb = x - eps;
  auto ub = x + eps;
  return lb < y && y < ub;
}

刚发现一个漏洞。最后一条语句应该是

return (x == y) || (lb < y && y < ub);

万一equal_to(0, 0);

不,这还不够。您的 eps 太低,可能应该乘以用于生成 xy 的步骤数(尽管这些错误 经常 取消,这不能保证。

此外,您的舍入效果可能会因灾难性取消而放大。如果 x 大约为 0.1,因为它是按 10.0 - 9.9 计算的,那么您应该使用 limits::epsilon * (10+9.9)。你太乐观了大约 100 倍。