我有一个令人费解的问题,我怀疑它与科学记数法和小数精度有关。这是我的代码的一部分:
def atan(x):
# Calculate arctan(1/x)
x = Decimal(x)
current_value = Decimal(0)
divisor = 1
x_squared = x * x
current_term = 1 / x
while True:
current_value += current_term
divisor += 2
current_term = (-current_term / x_squared) / divisor
print(current_term)
# The issue
if current_term == Decimal(0):
break
return current_value
print(atan(5))
这是基于公式atan(1/x) = 1/x - 1/(3x^3) + 1/(5x^5) - ...
但是,我发现每个循环迭代变小的current_term
进入4E-80000之类的值。由于我将小数精度getcontext().prec
设置为20,因此当前术语甚至不应支持这些值。我想某种方式current_term
不是十进制类型而是科学记数法/浮点类型,但是python告诉我它仍然是十进制类型。
arctan(1/5)的正确值约为0.1973955。我得到的值为0.1973545,从第5位开始是错误的。即使我手动打破循环,由于某种原因,值仍然是错误的。 任何解决此问题的帮助表示赞赏。
答案 0 :(得分:3)
您的代码与公式不符。从下一个推断一个术语有点太棘手了;-) 1/(5x^5)
术语不是1/(3x^3)
术语的倍数。
以下是直接为公式建模的代码:
from decimal import Decimal
def atan_recip(x):
# Calculate arctan(1/x)
x = Decimal(x)
total = Decimal(0)
sign = 1
for i in range(1, 35, 2):
total += sign / (i * x ** i)
sign = -sign
print(total)
atan_recip(5)
输出符合您的预期:
0.2
0.1973333333333333333333333333
0.1973973333333333333333333333
0.1973955047619047619047619047
0.1973955616507936507936507936
0.1973955597889754689754689754
0.1973955598519908535908535908
0.1973955598498063202575202575
0.1973955598498834214339908457
0.1973955598498806620234645299
0.1973955598498807618878454823
0.1973955598498807582406246127
0.1973955598498807583748423407
0.1973955598498807583698713137
0.1973955598498807583700564416
0.1973955598498807583700495142
0.1973955598498807583700497745