0

可能重复:
为什么十进制数不能用二进制精确表示?

语言 c++ 我正在声明一个数组并在其中保存数字(双精度类型)。然后我开始比较数组中每两个元素之间的差异。例如

a[1] = 0.05
a[2] = 0.1
a[3] = 0.15

所以当我执行以下操作时

if(a[3] - a[2] == a[2] - a[1] )

条件变为假!!

调试后发现0.05在数组中保存为0.0499......993,情况与0.10和0.15类似

我该如何克服这个问题?

4

4 回答 4

8

您永远不应该比较浮点数的精确相等性。

您应该阅读每个计算机科学家应该了解的关于浮点运算的知识,以找出原因。

于 2011-05-09T14:52:02.910 回答
3

如果您想进行精确计算,您可能需要考虑使用有理数。可以在 C++ 中实现一个有理数类。Boost.Rational就是一个例子。

如果你想使用浮点数,你可能想对“接近”进行比较,而不是相等,如下所示:

const float EPSILON = 0.0001; //< Some acceptable limit for equivalence
float d1 = a[3] - a[2];
float d2 = a[2] - a[1];

if (fabs(d1 - d2) < EPSILON) {
    // Consider d1 and d2 eqivalent
}
于 2011-05-09T14:54:18.990 回答
2

浮点数学是计算机不会像您通常期望的那样给出结果的一个领域。请参阅此内容以供参考。

你可以做的是考虑类似的事情 delta = 0.00001
并检查是否fabs((a[3]-a[2]) - (a[2]-a[1])) < delta

注意:如果这与货币或货币数据有关,则只需使用整数/长整数等。使用浮点数/双精度表示货币是一件坏事,原因如上所述并在上面的链接中进一步解释。

于 2011-05-09T14:52:48.730 回答
0

你有几个选择:

(1) 使用精确存储这些数字的类型。对于这些数字,最简单的方法可能是使用 int 并将它们存储为原始数字的 100 倍。

(2) 弄清楚比较双打是否相等是一个不好的策略。看,当您将数字存储为双精度数时,有些数字无法以固定位数的二进制精确表示。0.05(以及 0.5 5 50 等)就是这些数字之一。

于 2011-05-09T14:56:26.347 回答