zoukankan      html  css  js  c++  java
  • SICP学习笔记(2.1.4)

                                        SICP学习笔记(2.1.4) 
                                                周银辉

    1,练习2.7

    要得到答案,需注意到文中的一段话“Alyssa假设有一种称为区间的抽象对象,这种对象有两个端点,一个上界一个下界”,很明显,一个区间是由上界和下界来定义的,正如我们说平面上一个点是由其X坐标与Y坐标来定义的一样,所以,区间的定义函数便可写成:
    (define (make-interval a b) (cons a b))
    那么很自然的,求上界和下界的函数就如下了:
    ;定义上界
    (define (lower-bound x)
      (car x))
    ;定义下界
    (define (upper-bound x)
      (cdr x))

    2,练习2.8

    ;定义区间减法
    (define (sub-interval x y)
      (make-interval (- (lower-bound x) (lower-bound y))
                     (- (upper-bound x) (upper-bound y))))

    3,练习2.9

    我们先定义一下两倍区间宽度:
    (define (width x)
      (/ (- (upper-bound x) (lower-bound x)) 2.0))

     对于区间加减法,我们要证明的是“区间和差的宽带等于宽带之和差”,我们下面以“差”为列,简单证明下,其中Lx表示区间x的下界,Ux表示区间x的上界,Wx表示区间x的宽度的两倍(之所以要两倍,是为了下面的证明书写起来方便,每个表达式都除以2写起来太繁琐了):
         (width ( sub-interval x y))
    => (w (make-interval (- Lx Ly) (-Ux Uy)))
    => 由 (width x)的定义可知,其等于上界减去下界,而上面表达式中(make-interval (- Lx Ly) (-Ux Uy))的上界为(-Ux Uy) 下界为 (- Lx Ly),所以
    => (- (- Ux Uy) (- Lx Ly)))
    => 为了方便理解,将上面的表达式写成中缀的形式
    => ( Ux - Uy ) - (Lx - Ly)
    => Ux - Uy -Lx + Ly
    => (Ux - Lx) - ( Uy - Ly)
    =>根据Width的定义,所以
    => Wx - Wy
    所以“差的宽度,等于宽度之差”,求和同理。 
    乘除就不证明了,举个很简单的例子x=(2,4) y=(4,6),他们的积的宽度为8,而宽度之积为1.

    4,练习2.10

    非常简单,因为 y 的上下界要做分母,所以判断 其 是否为0:
    (define (div-interval x y)
      (if (or (= 0 (upper-bound y)) (= 0 (lower-bound y)))
          (display "division by zero")
          (mul-interval x
                    (make-interval (/ 1.0 (upper-bound y))
                                   (/ 1.0 (lower-bound y))))))

    5,练习2.11

    Ben 这句神秘的话可真让程序变得无比晦涩啊:
    (define (mul-interval x y)
      (let ((a (lower-bound x))
            (b (upper-bound x))
            (c (lower-bound y))
            (d (upper-bound y)))
        (cond ((< b 0)
               (cond ((< d 0)
                      (make-interval (* b d) (* a c)))
                     ((< c 0)
                      (make-interval (* a d) (* a c)))
                     (else
                      (make-interval (* a d) (* b c)))))
              ((< a 0)
               (cond ((< d 0)
                      (make-interval (* b c) (* a c)))
                     ((< c 0)
                      (let ((p1 (* a c))
                            (p2 (* a d))
                            (p3 (* b c))
                            (p4 (* b d)))
                        (make-interval (min p1 p2 p3 p4)
                                       (max p1 p2 p3 p4))))
                     (else
                      (make-interval (* a d) (* b d)))))
              (else
               (cond ((< d 0)
                      (make-interval (* b c) (* a d)))
                     ((< c 0)
                      (make-interval (* b c) (* b d)))
                     (else
                      (make-interval (* a c) (* b d))))))))

    6, 练习2.12

     (define (percent c p)
      (* p (/ c 100.0)))

    (define (make-center-percent c p)
      (let ((a (percent c p)))
        (make-interval (- c a) (+ c a))))

    7,练习2.13

    首先,我们假设 x 的误差为 deltaX,那么 x 值的变化范围为 (x ± deltaX),为了表示方便,我们用 dx 来代表 ± deltaX,那么x的值的变化范围是(x+dx),另外 x 的百分误差值就应该为 (dx / x ) * 100%

    然后,我们看两个具有误差的数 x 与 y 相乘:
          ( x + dx) * ( y + dy )
    => xy + x * dy + y * dx + dx * dy
    由于dx与dy很小,所以 dx*dy趋近于0,我们可以将其省略,上式变成:
    => xy + x * dy + y * dx
    不难理解,上式中的( x * dy + y * dx ) 是 xy 的误差,也就是说 xy 的变化范围是 xy + ( x * dy + y * dx)
    那么 xy 的百分误差  (( x * dy + y * dx)/ xy ) * 100%,  也就是 ( dy/y + dx/x ) * 100%

    8,练习2.14

    两种方法在数学上是对等的,但计算机的实际计算结果是不同的,代码如下:
    (define (make-interval a b) (cons a b))

    (define (lower-bound x)
      (car x))

    (define (upper-bound x)
      (cdr x))

    (define (add-interval x y)
      (make-interval (+ (lower-bound x) (lower-bound y))
                     (+ (upper-bound x) (upper-bound y))))

    (define (mul-interval x y)
      (let ((p1 (* (lower-bound x) (lower-bound y)))
            (p2 (* (lower-bound x) (upper-bound y)))
            (p3 (* (upper-bound x) (lower-bound y)))
            (p4 (* (upper-bound x) (upper-bound y))))
        (make-interval (min p1 p2 p3 p4)
                       (max p1 p2 p3 p4))))

    (define (div-interval x y)
      (mul-interval x
                    (make-interval (/ 1.0 (upper-bound y))
                                   (/ 1.0 (lower-bound y)))))

    (define (par1 r1 r2)
      (div-interval (mul-interval r1 r2)
                    (add-interval r1 r2)))
    (define (par2 r1 r2)
      (let ((one (make-interval 1 1)))
        (div-interval one
                      (add-interval (div-interval one r1)
                                    (div-interval one r2)))))

     (define (percent c p)
      (* p (/ c 100.0)))

    (define (make-center-percent c p)
      (let ((a (percent c p)))
        (make-interval (- c a) (+ c a))))

    (define (center i)
      (/ (+ (lower-bound i) (upper-bound i)) 2))

    (define a (make-center-percent 2 5))
    (define b (make-center-percent 3 6))

    (center (par1 a b))
    (center (par2 a b))
     
    两个中心点计算下来的结果分别是:1.2148016178736518 和 1.1999711093990755
    的确存在这样的差异,比如说 (1/3)*3 在数学上是等于1的,但在实际计算过程中,比如我们保留小数点后两位的精度,那么 1/3 等于 0.33 , 再乘以3,最后结果是0.99

     9,练习2.15

    感觉Eva Lu Ator说得有道理哈,比如数 a 在区间 (2,  3)之间,其误差为 ±0.5 ,  而 a^a 则在 (4,9)之间,误差值为 ±2.5

     

  • 相关阅读:
    微信验证代码
    微信内置浏览器的JS API
    伪类和伪元素
    asp.net core mvc 脚手架搭建过程介绍
    C#无锁内存队列
    关于微软OWIN的一篇好文章
    安装了Win10预览版10074,不能设置开发模式的bug解决
    关于Quartz的一些经历
    MEF接口应用初探
    简单的接口框架
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1590041.html
Copyright © 2011-2022 走看看