計算機プログラムの構造と解釈 第二版 P40 問題1.38

問題をよむ。


よし、サービス問題的なやつかなと思ったら、大間違いでした。
とりあえず、問題1.38で作ったcont-fracをつかって自然対数の底eを求める問題のようだ。
要はパラメータとして何を入れればいいかって言う部分を考えればいいのかな。


そこでとりあえずグーグルで自然対数の底eについて調べる。


自然体数の底eの定義
http://w3e.kanazawa-it.ac.jp/math/category/other/kyokugen/henkan.cgi?target=/math/category/other/kyokugen/e-no-teigi.html

自然対数の底 e の定義】

 自然対数の底 e は以下に示す極限の式で定義されている。

e= lim t→0 ( 1+t ) 1 t
t= 1 s とおくと, t→0 のとき s→0 となる。よって,上式は
e= lim s→∞ ( 1+ 1 s ) s

と表すこともできる。

e の値は,2.71828182845904・・・・・・・・・


まー e は 2.7182....ってことで。


問題本文に

eを自然数の底としてe-2の連分数展開がある。

ってことなので、この計算で求められるのは、どうやら、
0.7182...
の部分っぽい


最後に2をたす。。っと


んで、

Niはすべて1

余裕っすね。。。

Diは順に、1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8,.....

こういうの苦手なんだよね。


何時間考えたでしょうか、キリスト教だったかなんかだと、神は一週間かそこらで世界を作ったようですが、
僕は1週間近くこの問題を考えていたのでした。


ポイントは、iが2, 5, 8, 11っていうと時にDiがちょっと違うので、iの共通なルールを捉えればいい。
そうするとわかるのが、
3で割ると、2余る数ってことかな。


んで、そういうタイミングで何が起きるかというと、
Diが
2, 4, 6, 8
という値に、ううううむ。。。


いったん、さっきの3割ることについて考えてみる。
2 ÷ 3 = 0・・・ 2
5 ÷ 3 = 1・・・ 2
8 ÷ 3 = 2・・・ 2
11 ÷ 3 = 3・・・ 2


いったん、この答えに2を掛けてみると、、
0
2
4
6
で、さっきのDiの時は、、
2
4
6
8


あ、2ずつ足りない。
てことは、
2 * (1 + (i / 3))
って感じ。
ここの上の、(i / 3)は商だけ。



Scheme入門 2. Scheme を電卓代わりに使う
http://www.shido.info/lisp/scheme2.html

商を求めるにはquotient, 余りを求めるには remainder または modulo, 平方根を求めるには sqrt を使います。

ってことで、quotientという関数が使えるようです。



ということで、ソースです。

#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

;;回帰的(リカーシブ)プロセスヴァージョン
(define (cont-frac-r n d k)
  (define (cont-frac i)
    (if (< i k)
      (/ (n i) (+ (d i) (cont-frac (+ i 1) )))
      (/ (n i) (d i))))
  (cont-frac 1))


;;反復的(イテレーシブ)プロセスヴァージョン
(define (cont-frac-i n d k)
  (define (cont-frac i result)
    (if (= i 0)
      result
      (cont-frac (- i 1) (/ (n i) (+ (d i) result)))))
  (cont-frac (- k 1) (/ (n k) (d k))))





;; main
(define (main args)

  (display "e=2.71828182845904.... : ")
  (display (+ 2 (cont-frac-i
                   (lambda (i) 1.0)
                   (lambda (i) (if (= (remainder i 3.0) 2.0)
                                 (* 2.0 (+ 1.0 (quotient i 3)))
                                 1.0))
                   11) ))
  (newline)(newline)

0)


んで、結果

e=2.71828182845904.... : 2.7182818352059925


これ、できちゃった系っすね。