浮点数math.cos不准确

时间:2015-10-01 00:09:25

标签: c floating-point precision

我们知道cos(2mPI)= 1,对于每个整数m。 但是,我得到了以下输出。

value of m = 1.000000e+01 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+02 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+03 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+04 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+05 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+06 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+07 and value of cos(2*m*pi) = 1.000000000000000
value of m = 1.000000e+08 and value of cos(2*m*pi) = 0.999999999999997
value of m = 1.000000e+09 and value of cos(2*m*pi) = 0.999999999999998
value of m = 1.000000e+10 and value of cos(2*m*pi) = 0.999999999989970
value of m = 1.000000e+11 and value of cos(2*m*pi) = 0.999999999564035
value of m = 1.000000e+12 and value of cos(2*m*pi) = 0.999999854510183
value of m = 1.000000e+13 and value of cos(2*m*pi) = 0.999985451053279
value of m = 1.000000e+14 and value of cos(2*m*pi) = 0.999742535619873
value of m = 1.000000e+15 and value of cos(2*m*pi) = 0.888410566323832
value of m = 1.000000e+16 and value of cos(2*m*pi) = 0.718430574337184
value of m = 1.000000e+17 and value of cos(2*m*pi) = -0.438105159926831
value of m = 1.000000e+18 and value of cos(2*m*pi) = 0.176561618304251
value of m = 1.000000e+19 and value of cos(2*m*pi) = -0.114036978390490
value of m = 1.000000e+20 and value of cos(2*m*pi) = 0.689416156299807

为什么我们不总是计算正确的输出?随着m的值变大,近似值发生显着变化。不确定哪种类型的浮点误差导致了这种情况。有什么帮助吗?

2 个答案:

答案 0 :(得分:4)

这可能是因为PI本身的价值(它的计算机表示,而不是数学值)并不准确。

它可能是3.141592653589(这是我能记住的全部内容)但是,除非你有无限数量的位来存储它(或者你使用符号而不是二进制编码的形式),它永远不会完全准确。

而且,当你将它乘以更大的整数时,不精确度可能会增加。

浮点表示的变幻莫测是众所周知的,在这一点上,您只能从IEEE754双精度表示中获得大约十五位精度。给PI需要一个......好吧......永无止境的位数,这是必须给予的。

我不完全确定使用像1020π这样的值的应用程序是什么类型的,我不会假装知道你的情况,但你可能想要考虑一下试图将值限制在一个更“合理”的范围,如[0,2π)

答案 1 :(得分:2)

最接近的64位浮点数与PI(我称之为piDouble)和PI的确切值piExact之间的差值约为1.22E-16。差异m*piExact - m*piDouble == m*(piExact - piDouble)约为m*1.22E-16

像余弦这样的函数通过首先将角度减小到相对较小的角度范围来评估,在该角度范围内,库与余弦很接近。

随着m变大,m*1.22E-16首先变大到重要,然后在角度缩小结果中占主导地位。