2017-01-17 4 views
0

初めて&のスキームで実行すると、Leibniz formulaを使用してpiを計算する単純な再帰関数を作成しようとしています。この手順は、必要とされる精度を取り込み、適切なパイ近似を返す。例えばpi&scheme構文の系列近似の計算

:0.001-PI作る - > 3.14109 ...

イムは、しかし、構文に追いついたと戻り/スキームの変数を呼び出すための構文で失われた、適切な方法だばかり。

; Define count for number of loops, sum for pi estimate, and num/denom for calculating estimation in series 
(define count 1.0) 
(define sum 4.0) 
(define denomenator 3.0) 
(define numerator 4.0) 

; make-pi gets accuracy needed as input ie (make-pi 0.001 => 3.1410926536210413 
(define make-pi 
    (lambda (accuracy) 
    ; determine if next fraction will be + or - based on number of iterations thus far 
    (if (zero? sign count) 
     ; add fraction if odd, subtract otherwise 
     (+ sum (/ numerator denomenator)) 
     (- sum (/ numerator denomenator))) 
    (define (check-accuracy sum) 
     ; use check accuracy with current sum 
     (if (zero? check-accuracy) 
      ;return sum if within needed accuracy 
      sum 
      ; update count and new denom values if not accurate enough 
      ; loop back if sum is not accurate enough 
      (begin 
      (+ count 1) 
      (+ denomenator 2) 
      (make-pi (sum))))))) 



; if interation is even return 1 else 0 
(define sign 
    (lambda (count) 
    (if (even? count)) 
    1 
    0)) 

; if pi - sum is within desired accuracy, return 1 else 0 
(define check-sum 
    lambda (sum) 
    (define check-accuracy 
    lambda (accuracy) 

    (if ((- 3.14159265358979 sum) < (abs(accuracy)))) 
    1 
    0)) 
+0

ラケットは、実際にコードをフォーマットします。あなたの質問は何ですか? – Sylwester

+0

@Sylwesterありがとう、よく知っておいてください。私は構文を訂正しようとしています。例えば、系列を通るときに正しい分数を与えるためにsign手続きを使用する。変数を正しく定義していることを確認します。 – Silverfin

答えて

2

変数を呼び出す方法。

(add 1 2) ; returns 3 if `add` is like global variable `+` 

基本的にはアルゴル言語のadd(1, 2)にセマンティックeqvivalentです:シンボルaddあなたは括弧で囲んで呼び出す手順に評価することを考えます。 ((add 1 2))はadd(1, 2)()などと同じですので、余分な括弧を使用しないように注意してください。

変数を返す方法。さて、あなたはそれを尾の表現にしましょう。

(define (positive? n) 
    (if (> 0 n) 
     #t   ; tail that returns true 
     #f))  ; tail that returns false 

実際に何が起こるかifいずれかが結果として、またはテストに基づいて代替を行うことです。したがって、ifフォーム全体の結果はtrueまたはfalseになり、ifもその値を返します。最終的にはifという式の最後の式がpositive?の結果として返されます。

あなたはdefine

(define my-value 10) ; my-value is 10 

そしてもちろんの手順でグローバル変数を作成するには、値がされています。しかし(define sign (count))は、プロシージャを呼び出した結果であることを変数signを作成します

(define add1 (lambda (n) (+ n 1))) ; value of add1 is a procedure 

count引数なし。 var sign = count();(define check-accuracy lambda)var checkAccuracy = lambda;と同じで、おそらく結合されていません。あなたはおそらく代わりに(< (- 3.14159265358979 sum) (abs accuracy))をしたいスキームで sub(3.14159265358979, sum)(some-variable-<, abs(accuracy()))()

(((- 3.14159265358979 sum) < (abs(accuracy)))))は同じです。

define(ヘルパー)内の手順は、手順の本体の前に最初にある必要があります。例えば。

(define (fibonacci n) 
    ; define a local helper procedure 
    (define (helper n a b) 
    (if (zero? n) 
     a 
     (helper (- n 1) b (+ a b)))) 

    ; use the helper 
    (helper n 0 1)) 

そして(define (proc arg ...) body ...)はあなたが同じことを書くことができ(define proc (lambda (arg ...) body ...))と同じであるため:自由変数は、グローバル可能使用しない

(define fibonacci (lambda (n) 
    ; define a local helper procedure 
    (define helper (lambda (n a b) 
    (if (zero? n) 
     a 
     (helper (- n 1) b (+ a b))))) 

    ; use the helper 
    (helper n 0 1))) 

ヘルパー。彼らは自分自身でテストするのが簡単です。後でヘルパーとして内部に移動することができます。

(sign 1) ; ==> is it 0? 

言語を習うには時間がかかることを忘れないでください。これはおそらく新しい言語を学ぶ2番目の時間であり、すでに知っている言語の新しい方言を学ぶこととは異なるでしょう。

1

も再帰のために(説明のために、インラインコメントを参照してください)「という名前のLET」を使用することができますワン:あなたはCTRL +私は再フォーマットするために押すため

(define (myfn acc) 
    (let loop ((sum 0)       ; starting values 
      (denom 1) 
      (sign 1)) 
    (if (< (abs (- 3.14159265358979 sum))  ; check accuracy 
      (abs acc)) 
     (exact->inexact sum)     ; if accurate, end with output 
     (loop (+ sum (* 4 sign (/ 1 denom))) ; else loop again with next values 
       (+ 2 denom)      
       (if (= sign 1)-1 1)))))   
関連する問題