Exercise 1.39
A continued fraction representation of the tangent function was published in 1770 by the German mathematician J.H. Lambert:
tan x = x 1 − x 2 3 − x 2 5 − . . . \tan x = \frac{x}{1-\frac{x^2}{3-\frac{x^2}{5-...}}} tanx=1−3−5−...x2x2x
where x x x is in radians. Define a procedure ( t a n − c f x k ) (tan-cf\ x\ k) (tan−cf x k) that computes an approximation to the tangent function based on Lambert’s formula. k k k specifies the number of terms to compute, as in Exercise 1.37.
1.38难度不大,再加上今天周末,时间充足,我决定再做一道😀
1.39乍一看,并不很难,但是我想了半天也没做出来。直到我忽然发现
tan x = x 1 − x 2 3 − x 2 5 − . . . \tan x = \frac{x}{1-\frac{x^2}{3-\frac{x^2}{5-...}}} tanx=1−3−5−...x2x2x 其实等价于 x 2 1 − x 2 3 − x 2 5 − . . . ÷ x \frac{x^2}{1-\frac{x^2}{3-\frac{x^2}{5-...}}} \div x 1−3−5−...x2x2x2÷x
然后题目就变得简单了,只要把最后的结果除以 x x x 即可
; 注意 n 和 d 都是 procedure 而不是数字,k 表示要计算的项数
(define (cont-frac n d radians k)
; iterative implementation
(define (frac-iter i pre)
(if (= i 1)
pre
; 这里要注意计算的是 (d (- i 1)),而不是 (d i),否则会漏掉 1-... 这一项
(frac-iter (- i 1) (/ (n i) (- (d (- i 1)) pre)))))
; recurative implementation
(define (frac-recur i)
(if (= i k)
(/ (n i) (d i))
(/ (n i) (- (d i) (frac-recur (+ i 1))))))
(frac-iter k (square radians))) ; 注意初始值是 x^2
;(frac-recur 1))
; 注意到原式最上面的分子其实可以写成 x^2 / x,这样它的结构就可以保持一致,只要在最后把结果除以 x 即可
(define (tan-cf x k)
(let ((radians (/ (* pi x) 180)))
(/ (cont-frac (lambda (i) (square radians))
(lambda (i) (- (* 2 i) 1))
radians
k)
radians)))
; tan 30° ≈ 0.577,tan 45° = 1,tan 60° ≈ 1.732
(tan-cf 30 10)
(tan-cf 45 10)
(tan-cf 60 10)
; result
0.5773502691896257
1.0
1.7320508075688845