a. sum手続きは高階手続きとして書ける, 同様な数多い抽象の最も単純なものに過ぎない.51 与えられた範囲の点での関数値の積を返すproductという似た手続きを書け. productを使って, factorialを定義せよ. また式
b. 上のproductが再帰的プロセスを生成するなら, 反復的プロセスを生成するものを書け. 反復的プロセスを生成するなら, 再帰的プロセスを生成するものを書け.
π 2・4・4・6・6・8・・・ −=−−−−−−−−−−−−−−− 4 3・3・5・5・7・7・・・によってπの近似値を計算するのにproductを使え.
b. 上のproductが再帰的プロセスを生成するなら, 反復的プロセスを生成するものを書け. 反復的プロセスを生成するなら, 再帰的プロセスを生成するものを書け.
与えられた範囲の関数値の積を求める手続きproductを定義します.
和を積に変えているだけなので, sumの定義を利用できます.
手続きは次のようになります.
(require (lib "racket/trace.ss")) (define (inc x) (+ x 1)) (define (square x) (* x x)) ;; p.18のfactorialの定義 (define (factorial-0 n) (if (= n 1) 1 (* n (factorial-0 (- n 1))))) ;; productの定義. 再帰的プロセス (define (product-r term a next b) (if (> a b) 1 (* (term a) (product-r term (next a) next b)))) ;; productを用いたfactorialの定義 (define (factorial n) (product-r identity 1 inc n)) ;; 反復的プロセスを生成 (define (product-i term a next b) (define (iter a result) (if (> a b) result (iter (next a) (* (term a) result)))) (iter a 1)) ;; 円周率を求める. nが大きくなれば精度が良くなる. (define (my-pi n) (define (term x) (/ (* x (+ x 2)) (square (+ x 1)))) (define (next x) (+ x 2)) (* 4.0 (product-i term 2 next n)))
変更内容は, 「+」を「*」に, 初期値を0から1に変えているぐらいです.
factorialの定義には再帰的プロセスを生成するproductを使用し,
円周率の計算には反復的プロセスを生成productを使用しています.
また, 円周率を計算する式は, 次のようにカッコをつけると見やすくなります.
π 2・4 4・6 6・8 −=(−−−)・(−−−)・(−−−)・・・ 4 3・3 5・5 7・7
計算してみます.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (factorial-0 6) 720 > (factorial 6) 720 > (my-pi 10) 3.2751010413348074 > (my-pi 100) 3.1570301764551676 > (my-pi 1000) 3.1431607055322663 > (my-pi 10000) 3.1417497057380523 > (my-pi 100000) 3.1416083612781764 >
実行結果から, 円周率を計算できていそうです.
0 件のコメント:
コメントを投稿