双精度C ++

时间:2010-01-06 21:32:12

标签: c++ floating-point

我认为double的精确度导致了这个问题,正如在类似帖子中描述的那样,但我想知道是否有办法实现正确的结果。我正在使用比较两个参数的函数模板,如果它们相等则返回true。

template <class T>
bool eq(T one, T two)
{
  if (one == two)
    return true;
  else
    return false;
}

它适用于eq(0.8,0.8),但它不适用于eq(0.8 * 0.2,0.16)。正如我所提到的,我认为它与双精度有关,因为它也适用于int eq(8 * 2,16)。

6 个答案:

答案 0 :(得分:18)

首先,您应该阅读这些文章中的一个(或两个):What Every Computer Scientist Should Know About Floating-Point ArithmeticThe Perils of Floating Point

如果您正在寻找模板的解决方案,我建议您使用template specialization来处理T==doubleT==float的情况。

答案 1 :(得分:5)

你应该很少尝试比较双打的平等。相反,您需要决定您愿意接受的误差范围:

return fabs(one - two) <= 0.000001

答案 2 :(得分:3)

您需要重载函数,然后进行适合浮点的比较:

bool eq(double one, double two)
{
    // You'll want to choose a delta that is appropriate for your usage
    return fabs(one - two) < DELTA;
}

你还想为float做另一个重载。

答案 3 :(得分:2)

这是关于比较浮点数的问题的另一个article

  

比较平等

     

浮点数学并不准确。像0.2这样的简单值无法使用二进制浮点数精确表示,浮点数的有限精度意味着操作顺序的微小变化可能会改变结果。不同的编译器和CPU架构以不同的精度存储临时结果,因此结果将根据您的环境的详细信息而有所不同。如果您进行计算,然后将结果与某些预期值进行比较,那么您很可能无法获得预期的结果。

答案 4 :(得分:1)

在不指定精度的情况下,不应该比较浮点数。

这将返回false:

cout << (0.8 * 2 < 0.16 ? true : false) << endl;

但这将返回true:

cout << ((0.8 * 2 - 0.16) < 0.001 ? true : false) << endl;

答案 5 :(得分:0)

您始终可以使用舍入功能来确定。