我需要编写一个浮点比较函数(等于/不等于),但我最多只能使用C++98和boost库。我知道浮动比较应该包括epsilon,但是我不知道如何在不使用C++11的情况下编写这样的代码。
发布于 2019-11-13 17:40:18
一个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很少足够,有关详细信息,请参阅这。
发布于 2019-11-13 19:00:48
我知道浮点比较应该包括epsilon,但我不知道如何
您可以使用std::numeric_limits<float>::epsilon()获得“机器”epsilon。
然而,浮点相等与公差的比较并不像直接将绝对差与机器感应器进行比较那么简单。任何小的epsilon都会将比较转化为对大值的相等比较,这将使您获得零的错误容忍。
有意义的宽容比较,要求你知道你期望的是什么类型的值,它们的大小,它们的符号,你想要容忍的预期错误。
这个博客用复杂的细节来解释这个问题。它建议如下,这可能是合理的“通用”比较
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++中不允许的联合类型双关。
https://stackoverflow.com/questions/58842533
复制相似问题