计算 pi 和方案语法的级数近似值
Calculating a series approximation for pi & scheme syntax
我第一次使用 运行 方案并且正在尝试编写一个简单的递归函数,它将使用 Leibniz formula 计算圆周率。该过程采用所需的精度和 returns 适当的 pi 近似值。
例如:make-pi 0.001 -> 3.14109...
不过我对语法很感兴趣,并且迷失了call/return 方案中变量的语法和正确方法。
; 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))
如何调用变量。鉴于符号 add
通过将它们括在括号中来评估您调用的过程:
(add 1 2) ; returns 3 if `add` is like global variable `+`
基本上它是 Algol 语言中 add(1, 2)
的语义等价物。
注意不要使用额外的括号,因为 ((add 1 2)) 与 add(1, 2)()
等相同。
如何 return 一个变量。好吧,你让它成为尾巴表达式。
(define (positive? n)
(if (> 0 n)
#t ; tail that returns true
#f)) ; tail that returns false
实际上发生的情况是 if
根据测试执行结果或备选方案。因此,整个 if
形式的结果变为 true 或 false,并且 if
也 returns 该值。最终,恰好是 if
表达式的过程的最后一个表达式作为 positive?
.
的结果得到 returned
你用 define
创建了一个全局变量
(define my-value 10) ; my-value is 10
当然一个过程就是一个值:
(define add1 (lambda (n) (+ n 1))) ; value of add1 is a procedure
但是 (define sign (count))
将创建变量 sign
作为调用不带参数的过程 count
的结果。 var sign = count();
。 (define check-accuracy lambda)
与var checkAccuracy = lambda;
相同,可能未绑定。
(((- 3.14159265358979 sum) < (abs(accuracy)))))
等同于:
sub( 3.14159265358979, sum)(some-variable-<, abs(accuracy()))()
在 Scheme 中,您可能需要 (< (- 3.14159265358979 sum) (abs accuracy))
。
A define
(helper) 在过程中需要在过程主体之前的开头。例如。
(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?
记得花时间学习语言。这可能是您第二次学习一门新语言,这与学习您已经知道的语言的新方言不同。
也可以使用'named let'进行递归(描述见内联注释):
(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)))))
我第一次使用 运行 方案并且正在尝试编写一个简单的递归函数,它将使用 Leibniz formula 计算圆周率。该过程采用所需的精度和 returns 适当的 pi 近似值。
例如:make-pi 0.001 -> 3.14109...
不过我对语法很感兴趣,并且迷失了call/return 方案中变量的语法和正确方法。
; 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))
如何调用变量。鉴于符号 add
通过将它们括在括号中来评估您调用的过程:
(add 1 2) ; returns 3 if `add` is like global variable `+`
基本上它是 Algol 语言中 add(1, 2)
的语义等价物。
注意不要使用额外的括号,因为 ((add 1 2)) 与 add(1, 2)()
等相同。
如何 return 一个变量。好吧,你让它成为尾巴表达式。
(define (positive? n)
(if (> 0 n)
#t ; tail that returns true
#f)) ; tail that returns false
实际上发生的情况是 if
根据测试执行结果或备选方案。因此,整个 if
形式的结果变为 true 或 false,并且 if
也 returns 该值。最终,恰好是 if
表达式的过程的最后一个表达式作为 positive?
.
你用 define
(define my-value 10) ; my-value is 10
当然一个过程就是一个值:
(define add1 (lambda (n) (+ n 1))) ; value of add1 is a procedure
但是 (define sign (count))
将创建变量 sign
作为调用不带参数的过程 count
的结果。 var sign = count();
。 (define check-accuracy lambda)
与var checkAccuracy = lambda;
相同,可能未绑定。
(((- 3.14159265358979 sum) < (abs(accuracy)))))
等同于:
sub( 3.14159265358979, sum)(some-variable-<, abs(accuracy()))()
在 Scheme 中,您可能需要 (< (- 3.14159265358979 sum) (abs accuracy))
。
A define
(helper) 在过程中需要在过程主体之前的开头。例如。
(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?
记得花时间学习语言。这可能是您第二次学习一门新语言,这与学习您已经知道的语言的新方言不同。
也可以使用'named let'进行递归(描述见内联注释):
(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)))))