【发布时间】:2018-06-05 05:58:43
【问题描述】:
我为使用 epsilon 的双精度定义了一个比较函数,如下所示:What is the most effective way for float and double comparison?。如果它们的绝对差小于 epsilon,则两个双精度数不同。
如果我有双打 d1 和 d2,d2 = d1+epsilon,d1 不应该等于 d2,因为它们的差异是 epsilon。对吧?
它适用于某些值,但并非总是如此。它可能与架构或编译器有关?我应该怎么做才能改进我的比较功能?
#include <iomanip> // For std::setprecision
#include <iostream>
#include "math.h" // For fabs
const double epsilon = 0.001;
bool equal(const double &d1, const double &d2)
{
return fabs(d1-d2) < epsilon;
}
int main()
{
double d1 = 3.5;
double d2 = d1+epsilon;
// d2 = d1 + epsilon should not be equal to d1.
std::cout << std::setprecision(16) << "d1 = " << d1 << " d2 = " << d2 << std::endl;
bool eq = equal(d1,d2);
if (eq)
{
std::cout << "They should not be equal, but they are!" << std::endl;
}
else
{
std::cout << "They are not equal. OK!" << std::endl;
}
}
我的机器上的输出:
d1 = 3.5 d2 = 3.501
他们不应该相等,但他们是!
【问题讨论】:
-
"如果我有双打 d1 和 d2,其中 d2 = d1+epsilon,d1 不应该等于 d2,因为它们相差 epsilon。对吧?"不,完全一样的原因。
-
作为旁注,
std::setprecision流修饰符不会修改内置类型精度。您不能修改内置类型精度。 -
你没看到讽刺吗?您使用 epsilon 比较来解决浮点运算不精确的事实 - 然后期望涉及
epsilon的表达式的精确结果。d1+epsilon的精确数学值在double中无法表示,因此d2最终会稍微小一些。