三角関数や対数などの近似計算の方法を短い Ruby コードでご紹介。だいたいマクローリン展開です。
子供のころ何気なく sin とか log とか使っていて、ふと「コンピュータはどうやってこの値を計算してるんだろう」と思ったものです。そんな昔の自分に見せてあげたいエントリ。と言っても、今時のコンピュータは FPU 持ってるんでこんな計算してませんが。
なお、ちゃんとテストしてません。
三角関数
0 に近い方が精度高いです。99 とか 98 とかは適当に大きな数字。
def sin(x) r, f = 0, 1 1.step(99, 2) do |i| r += x ** i / f f *= -(i+1)*(i+2) end r end
def cos(x) r, f = 0, 1 0.step(98, 2) do |i| r += x ** i / f f *= -(i+1)*(i+2) end r end
def tan(x) sin(x) / cos(x) end
指数関数
def exp(x) v = t = f = 1.0 99.times do |i| t *= x / (i+1) v += t end v end
自然対数
マクローリン展開だと収束が遅すぎるので、log(x) = 2 artanh ( (x-1)/(x+1) ) の式で。それでも x が大きいと収束が遅い。
def log(x) v = t = e = (x - 1.0) / (x + 1.0) 999.times do |i| t *= e * e v += t / (i + 1.5) end v end
べき乗
def pow(x, y) exp(log(x) * y) end