将双打与双重文字进行比较?

时间:2011-05-17 08:37:58

标签: c++ comparison floating-point compare double

  

可能重复:
  How should I do floating point comparison?

不建议在C ++中比较double和double文字的相等性,因为我猜它是依赖于编译器的吗?

更准确地说,比较硬编码的双精度(源代码中的文字)和应该计算的双精度是不行的,因为计算结果的最后一个数字可以从1变化编译到另一个。这不标准化吗?

我听说这是在Knuth的TeXbook中提到的,是吗?

如果这一切都是真的,那么解决方案是什么?

4 个答案:

答案 0 :(得分:6)

你有点误解了这个建议。关键是浮点计算并不准确。发生舍入错误,精度逐渐丧失。采取像1.0/10.0这样简单的事情。结果应该0.1,但事实并非如此,因为0.1无法以浮点格式精确表示。所以实际结果会略有不同。无数其他操作也是如此,所以这一点与const双打无关。这与预期结果不准确无关。如果你执行一些结果1.0的计算,那么你不应该测试它与1.0的相等性,因为舍入错误可能意味着它实际上已经出现{{ 1}}而不是。

所以通常的解决方案是测试结果是否足够接近 0.9999999997。如果它接近,那么我们假设“它足够好”,并且表现得好像结果是1.0。

底线是严格相等很少用于浮点值。相反,您应该测试两个值之间的差异是否小于某个小值(通常称为 epsilon

答案 1 :(得分:1)

您所谈论的问题是由于舍入错误而导致的每个浮点数都会发生。您可以做的是定义一个epsilon并查看两个浮点数之间的差异是否小于此值。 E.g:

double A = somethingA();
double B = somethingB();

double epsilon = 0.00001;

if (abs(A - B) < epsilon)
  doublesAreEqual();

[编辑] 另请参阅此问题:What is the most effective way for float and double comparison?

答案 2 :(得分:0)

关键问题是浮点运算如何工作 - 它包括可以导致相等性evaluated wrong的舍入。这适用于所有浮点数,无论变量是否声明为const

答案 3 :(得分:0)

如果你进行浮点计算并且你需要与某些固定值进行比较,那么使用epsilon值来考虑精度误差总是更安全。

示例:

double calcSomeStuf();

if ( calcSomeStuf() == 0.1 ) { ...}

是一个坏主意

但是:

const double epsilon = 0.005

double calcSomeStuf();

if ( abs(calcSomeStuf() - 0.1) < epsilon ) { ...}

更安全(特别是考虑到0.1不能完全表示为双倍的事实)

这是必要的,因为当累积浮点运算时会出现舍入误差,并且由于浮点的性质,并非所有数字都可以精确表示