の近似によくスターリングの公式が用いられます。
これで十分なことも多いですが、もう少しよい近似を考えてみましょう。
積分で近似して、
この差を取ると、
summationの中は、
をテイラー展開すると、
だから、summationの中は、
右辺第一項はリーマン・ゼータ関数
の特殊値
が使えて、
右辺第3項は上と同様な積分による近似が使えて、
の右辺の第2項以降は、数値計算して、
from itertools import count eps = 1e-22 v = [] for m in count(4, 2): a = 1.0 / (m*(m+1)*2**m) if a / 2**m < eps: break for k in count(2): b = a / k**m if b < eps: break v.append(b) print(sum(sorted(v)))
0.000263942581577
ということが分かりました。
以上をまとめると、
さらに定数項をまとめると、
検証してみましょう。
from math import log for n in (10, 20, 30): S = sum(log(m) for m in range(1, n+1)) S2 = (n+0.5)*log(n+0.5)-n-1.0/(24*n+12)+0.41893853320467317 print(n, S-S2) >|| >|| 10 2.0936225819667698e-06 20 2.8191458056880947e-07 30 8.56364152923561e-08
およそ-3乗で誤差が減っていっていることが分かると思います。
が気持ち悪かったら、そこも展開すると、
となりました。