ln2を計算しよう

30分プログラム、その656。ln2を計算してみよう。
SICPによると、ln(2)=1-\frac{1}{2}+\frac{1}{3}-\frac{1}{4}+\cdotsらしいです。

本来は無限ストリームを使って解く問題ですが、今回は有限の長さのリストを使っています。そのせいで、第何項までで計算するかを指定しなければいけません。
無限ストリームを使わなかった理由は、ボクのSMLスキルが低いせいです。具体的には~1を書くのに5分ぐらいかかっています。

使い方

- ln2 100;
val it = 0.69817217931 : real

(* 正解 *)
- Math.ln 2.0;
val it = 0.69314718056 : real

ソースコード

fun $ (f,g) = f g;
infixr 9 $

fun range a b = if a >= b then [] else a::range (a+1) b;
fun to (a,b) = range a b;
infix to;

fun sign n = if n mod 2 = 0 then ~1 else 1;
fun term n = (real $ sign n) * 1.0/(real n);

fun ln2 n = foldl (op +) 0.0 $ map term (1 to n)