C++ 比较C+中的双值+;
我有以下代码用于双重比较。为什么我在执行时变得不平等C++ 比较C+中的双值+;,c++,C++,我有以下代码用于双重比较。为什么我在执行时变得不平等 #include <iostream> #include <cmath> #include <limits> bool AreDoubleSame(double dFirstVal, double dSecondVal) { return std::fabs(dFirstVal - dSecondVal) < std::numeric_limits<double>::epsil
#include <iostream>
#include <cmath>
#include <limits>
bool AreDoubleSame(double dFirstVal, double dSecondVal)
{
return std::fabs(dFirstVal - dSecondVal) < std::numeric_limits<double>::epsilon();
}
int main()
{
double dFirstDouble = 11.304;
double dSecondDouble = 11.3043;
if(AreDoubleSame(dFirstDouble , dSecondDouble ) )
{
std::cout << "equal" << std::endl;
}
else
{
std::cout << "not equal" << std::endl;
}
}
#包括
#包括
#包括
布尔值是双重相同的(双重dFirstVal,双重dSecondVal)
{
返回std::fabs(dFirstVal-dSecondVal)
ε定义为“机器ε(1与可表示的大于1的最小值之间的差值)”-来源。这大约是2.22045e-016
(来源)
如果要更改模糊因子,请与另一个小的双精度进行比较,例如:
bool AreDoubleSame(double dFirstVal, double dSecondVal)
{
return std::fabs(dFirstVal - dSecondVal) < 1E-3;
}
bool是双重相同的(双重dFirstVal,双重dSecondVal)
{
返回标准::fabs(dFirstVal-dSecondVal)<1E-3;
}
两个双打的ε为2.22045e-016
根据定义,ε是1和大于1的最小值之间的差值,即
可表示为数据类型
它们之间的差异大于此,因此返回false
()你的两个双打之间的差值是0.0003。std::numeric_limits::epsilon()比这个小得多。epsilon比0.0003小得多,所以它们显然不相等 如果您想查看它的工作原理,请检查
epsilon()
仅是1.0
与1.0
之后可表示的下一个值之间的差值,即实际最小值。库函数std::nextafter
可用于缩放任何量级数字的等精度测试
例如,使用std::nextafter
测试double
是否相等,方法是测试b是否都是比a高的下一个数字:
bool nearly_equal(double a, double b)
{
return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
&& std::nextafter(a, std::numeric_limits<double>::max()) >= b;
}
当然,使用浮点运算时,需要对计算精度进行分析,以确定表示错误是如何形成的,从而确定正确的最小因子。因为它们不相等?双精度的ε远比您想象的小。是什么让您相信它们应该相等?Print
Epsilon()
to stdout.@Als的可能重复不是重复,这里的数字明显不同。我们如何计算1E-3的值?这代表什么?它只是0.001
的一个常量。它不是计算出来的或其他任何东西,它只是一个您选择的常量。1E-3是-3的指数幂的10,即0.001,或者,在其他wo中rds:1/1000。你能解释清楚为什么这比测试优越吗,abs(a-b)std::numeric_limits::epsilon()
不能与大小不同于1.0
的值一起使用。相反,std::nextafter
可以用于获取任何大小的值的ε。因此,让我们声明..然后我将对您的答案进行投票。问题确实是浮点被视为定点并进行比较的趋势没有某种准确度分析。好吧,我试着编辑答案以便解释清楚,不幸的是,在同行评审之前,你无法阅读我的尝试
bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
{
double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;
return min_a <= b && max_a >= b;
}