我已经阅读了其他问题,例如由于浮点表示,sin(2π)不为零,但非常接近。这个很小的错误在我的代码中是没有问题的,例如,我可以四舍五入小数。
然而,当将2π与非常大的数字相乘时,误差会放大很多。答案应该是零(或接近),但要远离它。
我的想法根本上是做错了吗?如果不是,如何避免π的浮点数的误差余量作为周期数(2 * PI * X)→∞得到“放大”?
注意,最后3个结果均相同。任何人都可以解释为什么即使5)PI / 2确实大于4)还是为什么?即使鼻窦曲线有很大的偏移,PI / 2的增加仍然会产生不同的数字,对吧?
检查小数SIN(2 * PI)
print math.sin(math.pi*2)
结果= -2.44929359829e-16如预期→对于我的目的,此错误余量是可以的
将PI / 2添加到上面的代码中:SIN(2 * PI + PI / 2)
print math.sin((math.pi*2)+(math.pi/2))
结果:1.0预期
正在检查非常大的SIN(2 * PI * VERY LARGE NUMBER)(仍然期望接近于零)
print math.sin(math.pi*2*(415926535897932384626433832795028841971693993751))
结果:-0.759488037749超出预期->就我而言,此错误余量不正确
在上面的代码中添加PI / 2:SIN(2 * PI *非常大的数字+ PI / 2)(预期接近一个)
print math.sin((math.pi*2*(415926535897932384626433832795028841971693993751))+(math.pi/2))
如上所述,但我添加了PI / 2-期望得到1.0结果:-0.759488037749不是预期的-为什么当我添加PI / 2时,结果与上面相同(应该在窦曲线上移四分之一)
将随机数(8)添加到非常大的数,期望既不为1也不为0
print math.sin(math.pi*2*(415926535897932384626433832795028841971693993759))
如上所述,但我加了8-期望既不为0也不为1结果:-0.759488037749不是预期的-为什么当我添加8
这根本不适合使用双精度变量。
math.pi
的值仅正确到大约16位小数点(二进制为53位),因此,当将其乘以415926535897932384626433832795028841971693993751(159位)之类的数字时,将不可能获得有意义的结果。
您需要改用任意精度的数学库。例如,尝试使用mpmath
。告诉它您想要1000位精度,然后再次尝试求和:
mpmath
[所使用的算法为近似值,而值(例如pi)为近似值。因此$ \ pi \ cdot {SomeLargeNumber} $ will会有很大的误差(因为$ \ pi $的值是近似值)。使用的功能(由硬件?)将减少参数,也许使用稍有不同的$ \ pi $值。
请注意,浮点算术不满足实算术的公理。
如何避免
>>> import mpmath >>> mpmath.mp.prec=1000 >>> print(mpmath.sin((mpmath.pi*2*(415926535897932384626433832795028841971693993751))+(mpmath.pi/2))) 1.0
具有比math.sin(math.pi*2*VERY LARGE NUMBER)
大的错误余量?
您可以math.sin(math.pi*2)
很大的数字:
% 1
>>> math.sin(math.pi*2*(415926535897932384626433832795028841971693993751))
-0.8975818793257183
>>> math.sin(math.pi*2*(415926535897932384626433832795028841971693993751 % 1))
0.0