【发布时间】:2018-03-18 23:34:38
【问题描述】:
我尝试创建一个程序,根据“数学函数计算手册”中描述的基于泰勒级数的算法计算以 10 为底的对数(我通过我的大学图书馆找到了在线副本)。
StackOverflow 上的另一个问题给出了类似的算法,我现在找不到链接。
10.3.2 计算以十进制为底的对数
对于十进制底,以 10 为底的对数是自然选择,并且将参数分解为 指数和分数为我们提供了十进制表示: x = (−1)^s × f × 10^n,要么 f = 0,要么 f 在 [1/10, 1) 中。
如果 f ≤√1/10,设 f = 10 × f 和 n = n - 1,使得 f 现在在区间 (√1/10,√10] 内。然后引入变量的变化,a泰勒级数展开,以及该展开的多项式表示:
z = (f - 1)/( f + 1),
f = (1 + z)/(1 - z),
D = 2 log10(e)
= 2/log(10)
log10( f) = D × (z + z3/3 + z5/5 + z7/7 + z9/9 + z11/11 + · · · )
≈ D × z + z3Q(z2),多项式拟合将 D 包含在 Q(z2) 中。
对于 (√1/10,√10] 中的 f,我们的 z 大约在 [−0.5195,+0.5195] 范围内。与二进制情况相比,z 的范围更广需要更长的多项式,并且还使得校正项 z3Q (z2) 相对较大。它的大小不超过 |0.35z|,因此它只提供一个额外的十进制数字,而不是两个。z 的精确计算比二进制情况更容易:只需设置 z = fl(fl (f−12)−12)/fl(f+1)。
为此,我用 Python 编写了这个程序:
def log10(x):
n = 0.0 #Start exponent of base 10
while (x >= 1.0):
x = x/10.0
n+=1
# if x <= sqrt(1/10)
if(x<=0.316227766016838):
x = x*10.0
n = n-1
#Produce a change of variable
z = (x-1.0)/(x+1.0)
D = 4.60517018598809 #2*log10(e)
sum = z
for k in range(3,111,2):
sum+=(z**k)/k
return D*n*sum
我将结果与math.log10函数进行了比较,结果并不如预期。调试时我最大的问题是理解算法及其工作原理。
【问题讨论】:
-
我看到了一些小错误。 n可以变成0吗?在这种情况下,Dnsum 看起来像正确的表达式吗?并且 2*log10(e) 不是你在代码中的数字。
-
如果你试图让 x 进入
(sqrt(1/10), 1)的范围,你不应该在下限上花一点时间,就像在上限上一样吗?此外,您引用的算法指定了(sqrt(1/10), sqrt(10)]的边界;你在用不同的吗? -
而
D*n*sum的最后一步不能正确使用n。这意味着(sqrt(1/10), 1)中每个值的对数都是 0。大概你应该将它相加,而不是相乘? -
@ArndtJonasson 感谢您指出
2*log10(e)的错误值。我在 Excel 中计算时一定打错了。我已将其更改为0.868588964。 @abarnert你是绝对正确的。应添加n术语。我已将返回语句更改为return D*sum+n。关于您对下限的评论,我相信f变量太小的问题已经由if(x<=0.316227766016838)语句处理。我现在正在调试程序,但是通过这两个修复程序看起来好多了。谢谢! -
@abarnert 我现在明白你的意思了。将
if语句更改为while语句。
标签: python algorithm math elementary-functions