SICP 1.6-1.8

1.6
由于scheme应用序求值的性质,该函数会陷入循环(一直计算 improve guess x)

1.7

值过小,0.001这个精度远远不够...

值过大,由于浮点数精度有限,(比如使用IEEE754浮点数标准, 32位浮点数表示123456789这样的数会有严重的精度丢失), 所以无法得出正确求两个较大的数的差.

 1 (define (abs x)
 2   (if (>= x 0)
 3       x
 4       (- x)))
 5
 6 (define (average a b)
 7   (/ (+ a b) 2))
 8
 9 (define (improve guess x)
10   (average guess
11            (/ x guess)))
12
13 (define (good-enough? guess x)
14   (< (/ (abs (- (improve guess x)
15                 guess))
16         guess)
17      0.01))
18
19 (define (sqrt-iter guess x)
20   (cond ((good-enough? guess x) guess)
21         (else (sqrt-iter (improve guess x) x))
22         ))
23
24
25 (define (sqrt x)
26   (sqrt-iter 1.0 x))

---> 原则上可以的,但是其实精度损失是肯定的...

1.8

 1 (define (improve2 guess x)
 2   (/ (+ (/ x
 3            (* guess guess))
 4         (* 2 guess))
 5      3))
 6
 7 (define (good-enough2? guess x)
 8   (< (/ (abs (- (improve2 guess x)
 9                 guess))
10         guess)
11      0.01))
12
13 (define (cbrt-iter guess x)
14   (cond ((good-enough2? guess x) guess)
15         (else (cbrt-iter (improve2 guess x)
16                          x))))
17
18 (define (cbrt x)
19   (cbrt-iter 1.0 x))
时间: 2024-08-25 09:05:10

SICP 1.6-1.8的相关文章

SICP 习题 (1.46)解题总结

SICP 习题 1.46 要求我们写一个过程iterative-improve,它以两个过程为参数,其中一个参数用来检测猜测是否足够好,另一个参数用来改进猜测.过程iterative-improve应该返回另一个过程,所返回的过程接收一个参数作为初始猜测,然后不断改进猜测直到结果足够好.题目还要求我们使用iterative-improve重写1.1.7的sqrt过程和1.3.3节的fixed-point过程. 因为涉及到高阶函数,所以整个题目理解起来有一点点费劲.不过这道题作为第一章的收官题确实

SICP 1.19

解:这道题很有意思,结论是斐波那契数也可以用对数时间复杂度获得. 通过Tpq(Tpq)=TPQ建立方程,解得: P=pp+qq Q=qq+2pq 程序如下: (define (fib n)   (define (even? n)     (= (remainder n 2) 0))   (define (fib-iter a b p q count)     (cond ((= count 0) b)           ((even? count) (fib-iter a           

SICP 1.12

解: (define (pascal n)   (define (get n i)     (cond ((<= i 1) 1)           ((>= i n) 1)           (else (+ (get (- n 1) (- i 1))                    (get (- n 1) i)))))   (define (iter i n)     (if (<= i n)         (and (print (get n i))          

SICP 习题 (2.26)解题总结:列表操作符append cons list

SICP  习题 2.26 也是不需要太多解释的题目, 题目的主要目的是让读者理解append cons list三个操作的差别. 直接运行下面代码中的start-test-2-26过程就可以了,需要留意一下的是append 过程, cons过程和list过程的使用. 最好翻一下mit-schme的参考手册,对了,一直没有提mit-scheme的手册,建议大家去下载一份备用,需要的时候查一查 链接如下: http://www.gnu.org/software/mit-scheme/ 有pdf版可

SICP 习题 (2.16)解题总结:避免误差的区间计算系统

SICP 习题 2.16 问我们能不能设计一个没有问题的区间计算系统,可以避免习题2.14中的问题.题目还吓我们说这可能很难. 这一下就把我吓住了,你不是说很难吗,那就很难吧,我不会.呵呵

SICP 习题 (2.15)解题总结:区间误差的深入思考

SICP 习题 2.15 是接着 题目 2.14 的, 题目 2.14中提到了Alyssa设计的区间计算模块在并联电阻计算时会出现问题,这个问题是Lem发现的.接着,一个叫Eva的人也发现了这个问题,同时她还有更深入的思考. Eva觉得,如果一个公式可以写成一种形式,其中具有非准确性的变量不重复出现,那么Alyssa的系统产生的区间的限界会更紧一些. 因此,她觉得在计算并联电阻时,公式"1/(1/R1 + 1/R2)"比公式"(R1*R2)/ (R1 + R2)"要

SICP 习题 (1.45)解题总结

SICP 习题 1.45是对前面很多关于不动点的习题的总结. 题目回顾了我们之前在1.3.3节使用的不动点寻找方法,当寻找y -> x/y 的不动点的时候,这个变换本身不收敛,需要做一次平均阻尼才可以. 对于y -> x/(y^2)这个变换也可以通过一次平均阻尼使它变得收敛. 不过一次平均阻尼对于四次方程是不够的,就是说,对y -> x/(y^3)这样的变换,一次平均阻尼不足以使它收敛,需要做两次平均阻尼才行. 题目遵从一直以来的抽象原则,要求我们去多做几次测试,找出 y -> x

Racket 模拟SICP的流(延时计算)

默认的Racket是要对函数参数进行求值的, 例如(f 1 (+ 1 2))里面,(+ 1 2)要先求值为3,变为(f 1 3)再进行下一步操作.因此, Racket若按照SICP使用define关键字来定义延时计算的关键函数delay和cons-stream是不可行的, 需要用宏来定义,绕过求值. #lang racket (define (memo-proc proc) (let ((already-run? #f) (result #f)) (lambda () (if already-r

SICP 习题 (2.23)解题总结:for-each的实现

SICP 习题 2.23 要求我们实现一个for-each过程. for-each过程和map过程其实很像,只不过for-each过程不返回值,如果返回一个值的话也是不包含意义的值. map比较像一个加工厂,进去一堆东西,加工一下,出来另一堆东西. for-each更像一个蒸汽机,进去一堆煤,燃烧一下,产生能量干点活,不出来东西,真的一定要说有东西出来也是煤渣,大家不在乎的东西. 所以for-each更关注的是里面执行的操作. 其实for-each操作在我们日常使用的语言中都会有,如c语言里的f

SICP 习题 (2.21)解题总结: map的使用

SICP 习题 2.21 开始引入了map,准确来讲,是这道题目前的文章内容开始引入了map. 为了完成本习题,甚至说为了完成本文以后的阅读,请读者一定要理解清楚map的概念,正如书中所说,"map是一种很重要的结构,不仅因为它代表了一种公共模式,而且因为它建立起了一种处理表的高层抽象". 虽然说得非常高大上,但是map的概念理解起来并不困难,最基本的理解就是给你一组东西,你对这组东西执行map操作的话,就是把这组东西里面的成员逐个拿出来执行对应操作. 比如(map  做朋友  土豪们