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 件のコメント:
コメントを投稿