計算誤差について

講義で、浮動小数点演算での誤差の話になり、 e をテイラー展開して、C言語で近似計算してみようという実習があった。打ち切り誤差は当然として、講義の主眼は、浮動小数点演算では、加減乗除の順番によっては、誤差が大きくなることがありますよ、ということである。

みんながC言語を使うなか、私は、「Gauche でやります!」とのたまい、けげんな顔をした先生に向かって、「関数型言語を使うと、コードが数学の定義みたいになって、きれいに書けるんですよ、開発速度も段違いです!」と、こんなコードを目の前で書き上げた。

(use srfi-1)
(define (factorial n)
  (if (= n 0)
      1
      (* n (factorial (- n 1)))))

(define (tailor-expanding-for-e)
  (fold + 0 (map (lambda (n)
		   (/ 1 (factorial n)))
		 (iota 10))))

そして、勢い良くエンターキーを叩いて実行した。
スターンッ
すると、exact numberの 98641/36288 が表示された。

なんだね、それは。 という先生の視線。

「こ、これは、exact number という仕組みで、つまり分数みたいなもので、誤差がないんです。
・・・あ、こうすれば、誤差を生じさせることもできますよ!」

1 だったところを 1.0 にして実行して、
2.7182815255731922 と、ある意味、期待した数値が表示された。

誤差を小さくするための工夫についての講義なのに、わざわざ誤差を生じさせるという、なんだかおかしなことになってしまった。