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

Floating point comparison in general unit tests

本文关键字:比较 单元测试      更新时间:2023-10-16

我知道这个问题已经讨论了很多。我在网上搜索了一下,自己想出了一个算法。我想知道它是否可以作为一个默认实现,在一般的单元测试(而不是一些严肃/专业的数字测试)中运行良好。

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倍。