比较C ++中的double值

时间:2012-09-05 09:39:55

标签: c++

我有以下代码进行双重比较。我执行时为什么会变得不平等?

#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;
}
}

5 个答案:

答案 0 :(得分:13)

2个双打的epsilon是2.22045e-016

  

根据定义,epsilon是1和大于1的最小值之间的差值   可表示数据类型。

这些不同于此,因此,它返回false

(的 Reference

答案 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.01.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