4 回答
TA贡献1797条经验 获得超6个赞
请注意-1 ** n,它不会像您期望的那样被解析。 **比一元更紧密地绑定-(具有更高的优先级),所以这个表达式被解析为-(1 ** n). 类似于蓝牙解决方案,我会做类似的事情
from math import factorial, pow
from itertools import takewhile, count
large = lambda y: abs(y) > 1e-7
def sin_gen(x):
for n in count():
yield (pow(-1, n) * pow(x, (2 * n + 1))) / factorial(2 * n + 1)
def sin(x):
return sum(takewhile(large, sin_gen(x)))
print(sin(5)) # -0.9589242932128198
TA贡献1860条经验 获得超8个赞
这就是我的做法,它使用公式但不直接使用。
(-1) ** n
是前一个值乘以-1
。x ** (2n + 1)
是前一个值乘以x * x
。(2n + 1)!
是前一个值乘以2n * (2n + 1)
。
这意味着您的循环不进行幂或阶乘计算,这样效率更高。这是在Python中:
def approx_sin(x, eps=1e-7):
term = x
two_n = 0
total = 0
while abs(term) >= eps:
total += term
two_n += 2
term *= -x * x / (two_n * (two_n + 1))
return total
TA贡献1848条经验 获得超10个赞
鉴于这是一个无限系列,您可以创建一个生成器,给定x通过每次递增n来提供下一个评估。
from math import factorial, pow
def sin_gen(x):
n = 0
while True:
result = (pow(-1, n) * pow(x, (2 * n + 1))) / factorial(2 * n + 1)
yield result
n += 1
现在您只需对每个评估求和,直到总数达到您想要的为止。
g = sin_gen(x)
total = 0
for val in g:
if abs(val) < 1.0e-7:
break
total += val
print(total)
添加回答
举报