【发布时间】:2013-04-05 12:56:25
【问题描述】:
有没有办法获得角度的确切正切/余弦/正弦(以弧度为单位)?
math.tan()/math.sin()/math.cos() 没有给出某些角度的精确值:
>>> from math import *
>>> from decimal import Decimal
>>> sin(pi) # should be 0
1.2246467991473532e-16
>>> sin(2*pi) # should be 0
-2.4492935982947064e-16
>>> cos(pi/2) # should be 0
6.123233995736766e-17
>>> cos(3*pi/2) # 0
-1.8369701987210297e-16
>>> tan(pi/2) # invalid; tan(pi/2) is undefined
1.633123935319537e+16
>>> tan(3*pi/2) # also undefined
5443746451065123.0
>>> tan(2*pi) # 0
-2.4492935982947064e-16
>>> tan(pi) # 0
-1.2246467991473532e-16
我尝试使用 Decimal(),但这也无济于事:
>>> tan(Decimal(pi)*2)
-2.4492935982947064e-16
numpy.sin(x) 和其他三角函数也有同样的问题。
或者,我总是可以创建一个带有值字典的新函数,例如:
def new_sin(x):
sin_values = {math.pi: 0, 2*math.pi: 0}
return sin_values[x] if x in sin_values.keys() else math.sin(x)
但是,这似乎是一种廉价的解决方法。还有其他方法吗?谢谢!
【问题讨论】:
-
当使用浮点数的有限长度表示时,没有办法精确表示无理数。三角函数的结果通常是不合理的,因此无法在数字计算机上准确地表示它们。您所看到的是浮点数的限制,如果对于您的问题而言,值不足以接近 0,您可能需要重新考虑如何解决它。
-
更重要的是,
math.pi不完全是pi,所以即使sin是准确的,它也不会是0。 -
这是由于浮点计算的限制。有几种方法可以解决这个问题。符号计算,适当调整精度等。如果你说你想要什么,可能会有解决方案。
-
这就是浮点的本质,你无法绕过它。即使是 dict 查找也只适用于某些情况。例如 (52*math.pi) / 52 != math.pi