Gauss-Legendreの2次の収束公式でπを計算してみました
算術幾何平均による円周率πの計算公式を参考にπを計算してみました。多倍長演算をごにょごにょするのが大変そうだったので、とりあえずDoubleの範囲で。
module Main (main) where import Text.Printf (printf) calcPi :: Int -> Double calcPi n = calc n 1.0 (1.0 / (sqrt 2.0)) 1.0 4.0 where calc 0 a b t _ = (a + b) ^ 2 / t calc n a b t x = let a' = (a + b) / 2.0 b' = sqrt (a * b) t' = t - x * ((a - a') ^ 2) x' = x * 2 in calc (n - 1) a' b' t' x' main :: IO () main = mapM_ (starling (printf "n = %2d ... %f\n") calcPi) [1 .. 10] where starling f g x = f x $ g x -- => n = 1 ... 3.1405792505221686 -- n = 2 ... 3.141592646213543 -- n = 3 ... 3.141592653589794 -- n = 4 ... 3.141592653589794 -- n = 5 ... 3.141592653589794 -- n = 6 ... 3.141592653589794 -- n = 7 ... 3.141592653589794 -- n = 8 ... 3.141592653589794 -- n = 9 ... 3.141592653589794 -- n = 10 ... 3.141592653589794
うーん、3回も繰り返すとDoubleの範囲では収束するのか…
参照: ガウス=ルジャンドルのアルゴリズム - Wikipedia