我有以下代码进行双重比较。我执行时为什么会变得不平等?
#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;
}
}
答案 0 :(得分:13)
答案 1 :(得分:6)
不相等(根据您的功能),因为它们的差异超过epsilon
。
Epsilon被定义为“机器epsilon(1和最小值之间的差值,可以表示)” - 来源http://www.cplusplus.com/reference/std/limits/numeric_limits/。这大约是2.22045e-016
(来源http://msdn.microsoft.com/en-us/library/6x7575x3(v=vs.71).aspx)
如果您想更改捏造因子,请与另一个小双重进行比较,例如:
bool AreDoubleSame(double dFirstVal, double dSecondVal)
{
return std::fabs(dFirstVal - dSecondVal) < 1E-3;
}
答案 2 :(得分:5)
你的两个双打之间的差异是0.0003。 std :: numeric_limits :: epsilon()远小于此。
答案 3 :(得分:3)
epsilon()
只是1.0
与1.0
之后可表示的下一个值之间的差异,真正的最小值。库函数std::nextafter
可用于扩展任意大小的数字的等式精度测试。
例如,使用std::nextafter
来测试double
相等性,通过测试b是&lt; =下一个数字低于&amp;&amp;&amp; &gt; =下一个数字高于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;
}
当然,如果a&amp;的位模式只是true
。 b是一样的。所以这是一种效率低下的方法(不正确的)天真直接a == b比较,因此:
要测试两个double
在某个因子内的相等性,可以使用:
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;
}
当然使用浮点数时,需要分析计算精度来确定表示错误是如何形成的,以确定正确的最小因子。
答案 4 :(得分:2)
Epsilon远小于0.0003,所以它们显然不相等。
如果您想了解它的工作原理,请检查http://ideone.com/blcmB