SICP 1.06-1.08

原创 2016年08月30日 16:55:16

牛顿算法

(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

(define (improve guess x)
   (average guess (/ x guess)))

(define (average x y)
  (/ (+ x y) 2))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

(define (sqrt x)
  (sqrt-iter 1.0 x))

习题1.6

(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

(define (sqrt-iter guess x)
  (new-if (good-enough? guess x)
          guess
          ;应用序,先求值后判断,形成递归
          (sqrt-iter (improve guess x) x)))

Eva的算法,会无法停止。原因在于,MIT-Scheme(本人用的是Gambit-c),采用的是应用序求值方式。
if语句是特殊形式,而new-if是复合过程,采用应用来做替换,于是先计算子表达式,再做替换。但是子表达式中有一项是递归的,这样判断是否需要递归的操作还未执行,就开始执行递归了,于是递归就一直进行下去不能终止,直至超过scheme的递归深度限制。

习题1.7
参照: 测试方法

;num 表示初始值,test-times表示进行test-times次测试,每次测试将num平方作为新的num
;每进行一次测试,先显示num的平方,然后显示num,最后显示xysqrt对num的平方进行的开方操作
(define (sqrt-test num test-times)
  (begin (display (* num num))
         (newline)
         (display num)
         (newline)
         (display (sqrt (* num num)))
         (newline)
         (newline)
         (if (> test-times 0)
             (sqrt-test (* num num) (- test-times 1))
             num)))

(1).测试很小值

> (sqrt-test 0.1 5)
.010000000000000002
.1
.10032578510960607

1.0000000000000005e-4
.010000000000000002
.03230844833048122

1.0000000000000008e-8
1.0000000000000005e-4
.03125010656242753

1.0000000000000017e-16
1.0000000000000008e-8
.03125000000000106

1.0000000000000035e-32
1.0000000000000017e-16
.03125

1.0000000000000069e-64
1.0000000000000035e-32
.03125

1.0000000000000035e-32

发现当要计算的平方根小于0.1之后,所计算出的平方根都是0.03+,这是因为虽然计算的平方根相对于实际值误差很大,但是误差小于good-enough? 中设定的0.001。


(2).测试很大值

> (sqrt-test 5 5)
25
5
5.000023178253949

625
25
25.000000063076968

390625
625
625.0000000051539

152587890625
390625
390625.

23283064365386962890625
152587890625
1.52587890625e11

542101086242752217003726400434970855712890625
23283064365386962890625
*** INTERRUPTED IN ##exact-int->flonum

发现计算5的32次方时,程序计算时间过长。可能的原因是由于精度限制,计算的结果的小数位被省略,导致平方后的误差始终大于0.001,因此程序无法停止。


监视猜测值变化率的方案

(define (sqrt-iter guess pre-guess x)
  (if (good-enough? guess pre-guess)
      guess
      (sqrt-iter (improve guess x)
                 guess
                 x)))

(define (improve guess x)
   (/ (+ guess
         (/ x guess))
      2.0))

(define (good-enough? guess pre-guess)
  (< (/ (abs (- guess pre-guess))   ;变化率
        pre-guess)
     0.0001))

(define (sqrt x)
  (sqrt-iter 1.0 x x))

(1).测试很小值

> (sqrt-test 0.1 5)
.010000000000000002
.1
.10000000000139897

1.0000000000000005e-4
.010000000000000002
.010000000025490747

1.0000000000000008e-8
1.0000000000000005e-4
1.0000000000082468e-4

1.0000000000000017e-16
1.0000000000000008e-8
1.0000000009432513e-8

1.0000000000000035e-32
1.0000000000000017e-16
1.0000000000006089e-16

1.0000000000000069e-64
1.0000000000000035e-32
1.0000000000106228e-32

1.0000000000000035e-32

(2).测试很大值

> (sqrt-test 600 5)
360000
600
600.0000000016597

129600000000
360000
360000.0000546434

16796160000000000000000
129600000000
1.2960000000000047e11

282110990745600000000000000000000000000000000
16796160000000000000000
1.6796160000000008e22

79586611099464008843919360000000000000000000000000000000000000000000000000000000000000000
282110990745600000000000000000000000000000000
2.821109916634466e44

6334028666297327770616228694681188660989646182809600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
79586611099464008843919360000000000000000000000000000000000000000000000000000000000000000
7.958661110068303e88

79586611099464008843919360000000000000000000000000000000000000000000000000000000000000000

习题1.8

(define (cube-roots-iter guess pre-guess x)
  (if (good-enough? guess pre-guess)
      guess
      (cube-roots-iter (improve guess x)
                 guess
                 x)))

(define (improve guess x)
   (/ (+ (/ x
            (* guess guess))
         (* 2 guess))
      3))

(define (good-enough? guess pre-guess)
  (< (/ (abs (- guess pre-guess))   ;变化率
        pre-guess)
     0.0001))

(define (cube-roots x)
  (cube-roots-iter 1.0 x x))

SICP第三章学习笔记

第三章 模块化、对象和状态(Modularity, Objects, and State)     当我们需要模拟真实物理系统的程序时,我们可以采用基于被模拟的结构去设计程序的结构,这样,在需要针对系...
  • viredery
  • viredery
  • 2015年04月06日 14:55
  • 374

SICP学习小结

我一开始在看CSAPP,刚看完第一章,然后看见知乎上萧井陌发表的关于编程入门的新文章。他的推荐是先掌握一门语言比如Python然后看SICP,接着才是CSAPP。我查了一下发现只有400多页,就打算2...
  • viredery
  • viredery
  • 2015年04月13日 18:57
  • 904

SICP-Python版本(1.7)

因为无意中看见有人推荐的伯克利的这本教材,使用python教SICP,感觉使用起来更得心应手,毕竟scheme的括号太多用起来不习惯…虽然python不能支持所有的FP特性,但是作为一个初学者,让自己...
  • pp634077956
  • pp634077956
  • 2016年07月10日 23:10
  • 1989

sicp in python 资源

sicp in python
  • abc_1234d
  • abc_1234d
  • 2017年06月21日 09:26
  • 642

SICP学习笔记 (2.2.4)

                                                            SICP学习笔记 (2.2.4)                        ...
  • zhouyinhui
  • zhouyinhui
  • 2009年12月20日 08:01
  • 1130

SICP chapter2 put get

自己在做的时候挺不方便的附上put get代码帮助需要的朋友们 (define (make-table) (let ((local-table (list '*table*))) (defin...
  • zb1030415419
  • zb1030415419
  • 2016年05月23日 12:36
  • 176

SICP 习题 (1.6) 解题总结:对if语句的特殊处理

SICP 习题 1.6 还是讲的正则序和应用序,问题是从if过程的讨论开始的,习题说到名叫Alyssa P. Hacker的人觉的不需要为if提供一种特殊形式,可以直接用常规过程调用cond来实现。 ...
  • keyboardOTA
  • keyboardOTA
  • 2013年08月14日 06:58
  • 4174

SICP 折腾之开发环境

SICP 开发环境
  • zlf_jack
  • zlf_jack
  • 2014年11月01日 10:43
  • 1368

sicp in python

gitbook英文书:https://www.gitbook.com/book/wizardforcel/sicp-in-python/details中文翻译版:https://github.com/...
  • yz764127031
  • yz764127031
  • 2017年05月08日 21:25
  • 410

SICP中查询系统的实现

这里的查询系统实现了
  • u012839273
  • u012839273
  • 2014年10月28日 09:18
  • 328
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SICP 1.06-1.08
举报原因:
原因补充:

(最多只允许输入30个字)