2011-02-23 66 views
0

当我期待{-0.707107,0,0.707107}时,我正在做一些计算,导致值为{-0.707107,9.61481e-017,0.707107} 。第二个组成部分虽然基本为零,但会不会导致问题出现?我应该做些什么吗?使用C++双打。导致数字基本为零的浮点运算

+1

这真的取决于您的应用程序所需的准确性。舍入错误会随着时间累积,只有您知道它是否适用于您的应用程序。 – driis 2011-02-23 19:01:48

回答

6

这很大程度上取决于您打算在路上做什么。 :-)但是,获得与“数学”结果应该非常接近但不完全相等的结果是使用浮点数时必须遵守的。一个常见的解决方案是定义一些“epsilon”值(例如,1e-10),并在所有比较中接受epsilon的错误 - 因此x == y将变为fabs(x - y) < epsilon

+1

如果您正在使用的计算总是导致小数数量有限(你显然不会,因为你的数字似乎非常接近'的sqrt(2)'),例如货币计算,你应该避免浮点/在双工作所有的成本,并使用固定的精度数据类型(例如从[GNU多精度算术库](http://gmplib.org/)),或缩放所有数字,以便您可以使用整数。 – 2011-02-23 19:07:21

+0

Erm - 'sqrt(2)/ 2',即... – 2011-02-23 19:18:58

1

是的,他们可能会导致问题,当与0.比较使用==:这将返回false。 @driis指出,这种舍入误差也可能会累积。

您可以对此做些什么:不是使用==进行比较,而是使用允许舍入误差的比较和/或在算法中适当的点丢弃低于合理阈值的值,具体取决于您想要做的价值观。

查看任何关于数值算法的好书。

0

您只能安全地使用==比较某些值的浮点数,并且即使只有当您直接赋值这些值时,也不能将其用于任何计算结果。

通常你定义一个函数

bool isEqual(double a,double b) { 
    return fabs(a-b) < 0.0000001; // depends on the precision of your application 
} 

bool isClose(double a,double b) { 
    return fabs(a-b) < 0.001; 
} 
5

他们只会“造成的问题”如果你(一)正在做一个数值不稳定计算(你可能都没有)或(b)以后会尝试比较他们使用严格的平等。一般来说,你不应该“做些什么”,你应该确保你的算法不会对少量的不精确性过度敏感。