我需要编写一个浮点比较函数(等于/不等于),但我最多只能使用C ++ 98和boost库。我知道浮点比较应该包含epsilon,但是我不知道如何在不使用C ++ 11的情况下编写此类代码。
答案 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 ++中不允许的联合类型修剪。