C ++ 98中的浮点比较

时间:2019-11-13 17:28:37

标签: c++ floating-point c++98

我需要编写一个浮点比较函数(等于/不等于),但我最多只能使用C ++ 98和boost库。我知道浮点比较应该包含epsilon,但是我不知道如何在不使用C ++ 11的情况下编写此类代码。

2 个答案:

答案 0 :(得分:1)

一个C ++ 98示例:

#include <cmath>
#include <limits>
#include <iostream>

inline bool equal_with_tolerance(float a, float b, float tolerance = std::numeric_limits<float>::epsilon()) {
    return std::abs(a - b) < tolerance;
}

int main() {
    float a = 0.1f;
    float b = 0.1000001f;
    std::cout << (a == b) << '\n';                    // Outputs 0.
    std::cout << equal_with_tolerance(a, b) << '\n';  // Outputs 1.
}

tolerance取决于您的问题领域,很少使用std::numeric_limits<float>::epsilon,有关更多详细信息,请参见this

答案 1 :(得分:1)

  

我知道浮动比较应包含epsilon,但我不知道如何

您可以使用std::numeric_limits<float>::epsilon()来获得“机器”ε。

但是,具有公差的浮点相等比较并不像直接将绝对差与机器epsilon比较那样简单。任何小的epsilon都会将比较分解为大数值的等式比较,从而使您的容错率为零。

有意义的容忍比较,要求您知道您期望的是哪种值,它们的大小,其符号,希望承受的期望误差。

blog详细解释了该问题。它建议遵循以下条件,这对于“一般”比较可能是合理的

bool AlmostEqualRelativeAndAbs(float A, float B,
            float maxDiff, float maxRelDiff = FLT_EPSILON)
{
    // Check if the numbers are really close -- needed
    // when comparing numbers near zero.
    float diff = fabs(A - B);
    if (diff <= maxDiff)
        return true;

    A = fabs(A);
    B = fabs(B);
    float largest = (B > A) ? B : A;

    if (diff <= largest * maxRelDiff)
        return true;
    return false;
}

该示例在C语言中进行,但对于转换为C ++习惯用语而言却微不足道。本文中还有一个基于ULP的函数,但其​​实现依赖于C ++中不允许的联合类型修剪。