在比较浮点数时使用 epsilon 是否会破坏严格弱排序?

Jar*_*d42 4 c++ floating-point epsilon strict-weak-ordering

以下课程是否打破了严格的弱排序(与常规相比std::less(因此忽略边缘情况值,例如 Nan))

struct LessWithEpsilon
{
    static constexpr double epsilon = some_value;
    bool operator() (double lhs, double rhs) const
    {
        return lhs + epsilon < rhs;
    }
};

LessWithEpsilon lessEps{};
Run Code Online (Sandbox Code Playgroud)

Jar*_*d42 5

来自https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings

  1. 不可比性的传递性:对于所有xyzin S,如果x与 不可比y(意味着既不是x < y也不y < xtrue)并且如果y与 不可比z,则x与 不可比z

同样,来自https://en.cppreference.com/w/cpp/named_req/Compare

如果equiv(a, b) == true and equiv(b, c) == true,那么equiv(a, c) == true

有了{x, y, z} = {0, epsilon, 2 * epsilon},这条规则就被打破了:

  • !lessEps(x, y) && !lessEps(y, x) && !lessEps(y, z) && !lessEps(z, y) 但是lessEps(x, z)
  • equiv(x, y) == true and equiv(y, z) == true但是equiv(x, z) == false(作为x + epsilon < z

因此,该类打破了严格弱序。

  • @MarekR:在审查过程中,我看到了这个问题。我的同事要求参考,但我没有找到直接答案,所以我创建了这个答案(我认为这可能对其他人有帮助)。 (3认同)