该系列仅在 x 1,您将需要不同的系列。
比如这个(找到here):
def ln(x): return 2*sum(((x-1)/(x+1))**i/i for i in range(1,100,2))
输出:
ln(2.7) # 0.9932517730102833
math.log(2.7) # 0.9932517730102834
请注意,随着 x 变大,收敛需要超过 100 个项(直到它变得不切实际)
您可以通过添加 x 的较小因子的对数来弥补这一点:
def ln(x):
if x > 2: return ln(x/2) + ln(2) # ln(x) = ln(x/2 * 2) = ln(x/2) + ln(2)
return 2*sum(((x-1)/(x+1))**i/i for i in range(1,1000,2))
您也可以在基于 Taylor 的函数中执行此操作以支持 x>1:
def log(x):
if x > 1: return log(x/2) - log(0.5) # ln(2) = -ln(1/2)
n=1000
s=0
for i in range(1,n):
s += ((-1)**(i+1))*((x-1)**i)/i
return s
当 x 接近于零时,这些数列还需要更多项来收敛,因此您可能还希望在另一个方向上对它们进行处理,以保持计算的实际值在 0.5 和 1 之间:
def log(x):
if x > 1: return log(x/2) - log(0.5) # ln(x/2 * 2) = ln(x/2) + ln(2)
if x < 0.5: return log(2*x) + log(0.5) # ln(x*2 / 2) = ln(x*2) - ln(2)
...
如果性能是一个问题,您需要将 ln(2) 或 log(0.5) 存储在某处并重复使用,而不是在每次调用时都计算它
例如:
ln2 = None
def ln(x):
if x <= 2:
return 2*sum(((x-1)/(x+1))**i/i for i in range(1,10000,2))
global ln2
if ln2 is None: ln2 = ln(2)
n2 = 0
while x>2: x,n2 = x/2,n2+1
return ln2*n2 + ln(x)