計算機プログラムの構造と解釈(SICP)学習メモ
蒋 いつ峰 2008/08/03   |  プログラミング基礎
第一章 練習1.29〜1.33 2008/08/03  |  PK:SICP 練習 1.29〜1.33

プロシジャーを引数にする(delegate)。


問題

練習1.29:Simpson’s ruleで積分を求める。
練習1.30:Sumの反復版。
練習1.31:再帰と反復でπを求める。
練習1.32と1.33を
略します。


解答

練習1.29の解答

 
  1. /** 
  2.  * 練習1.29。 
  3.  * Simpson’s ruleで積分を求める。 
  4.  */  
  5. float simpson(float delegate(float x) f, float a, float b, int n) {  
  6.     float h = (b - a) / n;  
  7.     float y(int k) {  
  8.         return f(a + k * h);  
  9.     }  
  10.       
  11.     float ret = y(0);  
  12.     for (int i = 1; i < n; i++) {  
  13.         if (i % 2 == 0) {  
  14.             ret += 2 * y(i);  
  15.         } else {  
  16.             ret += 4 * y(i);  
  17.         }  
  18.     }  
  19.     ret += y(n);  
  20.     return (h / 3) * ret;  
  21. }  
  22.   
  23.   
  24. void main() {  
  25.     float cube(float x) {  
  26.         return x * x * x;  
  27.     }  
  28.   
  29.     float ret;  
  30.     ret = simpson(&cube, 0, 1, 100);  
  31.     Stdout.formatln("simpson(cube, 0, 1, 100) = {0:d16}", ret);  
  32.   
  33.     ret = simpson(&cube, 0, 1, 1000);  
  34.     Stdout.formatln("simpson(cube, 0, 1, 1000) = {0:d16}", ret);  
  35. }  

実行結果。

simpson(cube, 0, 1, 100) = 0.2500000000000000
simpson(cube, 0, 1, 1000) = 0.2500000894069672

n が大きい時精度が高いはずですが、逆に落ちています(精確値が 0.25)。何故か分からないです。分かる方でございましたら、教えてください。


練習1.30の解答

(define (sum term a next b)
  (define (iter a result)
    (if > a b)
        result
        (iter (next a) (+ result (term a)))))
  (iter a 0))


練習1.31の解答

 

 
  1. /** 
  2.  * 練習1.31。 
  3.  * 再帰と反復でπを求める。 
  4.  */  
  5. static float term(int n) {  
  6.     if (n == 2) {  
  7.         return 2f / 3f;  
  8.     }  
  9.     float x = cast(float) n;  
  10.     return (x / (x - 1)) * (x / (x + 1));  
  11. }  
  12.   
  13. static int next(int k) {  
  14.     return k + 2;  
  15. }  
  16.   
  17. // 再帰版  
  18. float product(float function(int n) term, int function(int k) next, int a, int b) {  
  19.     if (a > b) {  
  20.         return 1f;  
  21.     }  
  22.     return term(a) * product(term, next, next(a), b);  
  23. }  
  24.   
  25. float pi(int n) {  
  26.     // n is even number  
  27.     return 4 * product(&term, &next, 2, n);  
  28. }  
  29.   
  30. // 反復版  
  31. float product2(float function(int n) term, int function(int k) next, int a, int b) {  
  32.   
  33.     float iter(int a, float result) {  
  34.         if (a > b) {  
  35.             return result;  
  36.         }  
  37.         return iter(next(a), term(a) * result);  
  38.     }  
  39.   
  40.     return iter(a, 1);  
  41. }  
  42.   
  43. float pi2(int n) {  
  44.     return 4 * product2(&term, &next, 2, n);  
  45. }  

 

実行結果。

---- 1.31 ----
pi(10) = 3.0021762847900391
pi(100) = 3.1260795593261719
pi(1000) = 3.1400253772735596
pi(10000) = 3.1412661075592041
--------
pi2(10) = 3.0021758079528809
pi2(100) = 3.1260778903961182
pi2(1000) = 3.1400227546691895
pi2(10000) = 3.1413297653198242

 


閲覧  |  コメント  |  目次

 
ヘルプ  |  ご利用規約  |  相互リンク  |  問合せ
リンクはご自由に、問合せはお気軽に
©2007 Uprush