首页 > 其他分享 >sicp每日一题[2.77]

sicp每日一题[2.77]

时间:2024-11-14 19:29:20浏览次数:1  
标签:real 每日 complex 2.77 sicp magnitude part imag define

Exercise 2.77

Louis Reasoner tries to evaluate the expression (magnitude z) where z is the object shown in Figure 2.24. To his surprise, instead of the answer she gets an error message from apply-generic, saying there is no method for the operation magnitude on the types (complex). He shows this interaction to Alyssa P. Hacker, who says “The problem is that the complex-number selectors were never defined for complex numbers, just for polar and rectangular numbers. All you have to do to make this work is add the following to the complex package:”

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)

Describe in detail why this works. As an example, trace through all the procedures called in evaluating the expression (magnitude z) where z is the object shown in Figure 2.24. In particular, how many times is apply-generic invoked? What procedure is dispatched to in each case?


这道题我想的是先把代码跑起来,因为直接按题目提示添加了那4行代码还是会报错,最终能运行的代码如下:

(define (install-rectangular-package)
  ;; internal procedures
  (define (real-part z) (car z))
  (define (imag-part z) (cdr z))
  (define (make-from-real-imag x y) (cons x y))
  (define (magnitude z)
    (sqrt (+ (square (real-part z))
             (square (imag-part z)))))
  (define (angle z)
    (atan (imag-part z) (real-part z)))
  (define (make-from-mag-ang r a)
    (cons (* r (cos a)) (* r (sin a))))
  ;; interface to the rest of the system
  (define (tag x) (attach-tag 'rectangular x))
  (put 'real-part '(rectangular) real-part)
  (put 'imag-part '(rectangular) imag-part)
  (put 'magnitude '(rectangular) magnitude)
  (put 'angle '(rectangular) angle)
  (put 'make-from-real-imag 'rectangular
       (lambda (x y) (tag (make-from-real-imag x y))))
  (put 'make-from-mag-ang 'rectangular
       (lambda (r a) (tag (make-from-mag-ang r a))))
  'done)

(define (install-polar-package)
  ;; internal procedures
  (define (magnitude z) (car z))
  (define (angle z) (cdr z))
  (define (make-from-mag-ang r a) (cons r a))
  (define (real-part z) (* (magnitude z) (cos (angle z))))
  (define (imag-part z) (* (magnitude z) (sin (angle z))))
  (define (make-from-real-imag x y)
    (cons (sqrt (+ (square x) (square y)))
          (atan y x)))
  ;; interface to the rest of the system
  (define (tag x) (attach-tag 'polar x))
  (put 'real-part '(polar) real-part)
  (put 'imag-part '(polar) imag-part)
  (put 'magnitude '(polar) magnitude)
  (put 'angle '(polar) angle)
  (put 'make-from-real-imag 'polar
       (lambda (x y) (tag (make-from-real-imag x y))))
  (put 'make-from-mag-ang 'polar
       (lambda (r a) (tag (make-from-mag-ang r a))))
  'done)

;; 复数
(define (install-complex-package)
  ;; imported procedures from rectangular and polar packages
  (define (make-from-real-imag x y)
    ((get 'make-from-real-imag 'rectangular) x y))
  (define (make-from-mag-ang r a)
    ((get 'make-from-mag-ang 'polar) r a))
  ;; internal procedures
  (define (add-complex z1 z2)
    (make-from-real-imag (+ (real-part z1) (real-part z2))
                         (+ (imag-part z1) (imag-part z2))))
  (define (sub-complex z1 z2)
    (make-from-real-imag (- (real-part z1) (real-part z2))
                         (- (imag-part z1) (imag-part z2))))
  (define (mul-complex z1 z2)
    (make-from-mag-ang (* (magnitude z1) (magnitude z2))
                       (+ (angle z1) (angle z2))))
  (define (div-complex z1 z2)
    (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
                       (- (angle z1) (angle z2))))
  ;; interface to rest of the system
  (define (tag z) (attach-tag 'complex z))
  (put 'add '(complex complex)
       (lambda (z1 z2) (tag (add-complex z1 z2))))
  (put 'sub '(complex complex)
       (lambda (z1 z2) (tag (sub-complex z1 z2))))
  (put 'mul '(complex complex)
       (lambda (z1 z2) (tag (mul-complex z1 z2))))
  (put 'div '(complex complex)
       (lambda (z1 z2) (tag (div-complex z1 z2))))
  (put 'make-from-real-imag 'complex
       (lambda (x y) (tag (make-from-real-imag x y))))
  (put 'make-from-mag-ang 'complex
       (lambda (r a) (tag (make-from-mag-ang r a))))
  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)
  'done)

(define (make-complex-from-real-imag x y)
  ((get 'make-from-real-imag 'complex) x y))
(define (make-complex-from-mag-ang r a)
  ((get 'make-from-mag-ang 'complex) r a))

(define (real-part z) (apply-generic 'real-part z)) 
(define (imag-part z) (apply-generic 'imag-part z)) 
(define (magnitude z) (apply-generic 'magnitude z)) 
(define (angle z) (apply-generic 'angle z))

(install-rectangular-package)
(install-polar-package)
(install-complex-package)


(define z (make-complex-from-real-imag 3 4))
(magnitude z)

; 结果如下
5.000000000053722

这里要注意2点,一个是要安装这几个包,另一个是在安装这些包之前需要加上 (define (magnitude z) (apply-generic 'magnitude z)),不然会报错。
执行 (magnitude z) 的函数调用依次是:

(magnitude z)
(magnitude '(complex rectangular 3 . 4))
(apply-generic 'magnitude '(complex rectangular 3 . 4))
(get 'magnitude '(complex))
(apply magnitude (map contents '((complex rectangular 3 . 4))))

(magnitude '(rectangular 3 . 4))
(apply-generic 'magnitude '(rectangular 3 . 4))
(get 'magnitude '(rectangular))
(apply magnitude-rectangular (map contents '((rectangular 3 . 4))))
(magnitude-rectangular '(3 . 4))
5

为了看得更清楚,这里用 magnitude-rectangular 表示 install-rectangular-package 包中的 magnitude 过程。可以看出,在上面的过程中,一共调用了2次 apply-generic,第一次它根据 complex 和 magnitude 去寻找 install-complex-package 包中对应的过程;第二次它根据 rectangular 和 magnitude 找到了 install-rectangular-package 包中的 magnitude 过程。

标签:real,每日,complex,2.77,sicp,magnitude,part,imag,define
From: https://www.cnblogs.com/think2times/p/18546635

相关文章

  • 每日一题:https://www.luogu.com.cn/problem/P2249
    includeusingnamespacestd;intmain(){intp,sum;cin>>p>>sum;intarr[p];for(inti=0;i<p;i++){cin>>arr[i];}for(inti=1;i<=sum;i++){intmubiao;intmin=0;intmax=p-1;cin>>mubiao;for(;......
  • 每日一题 :https://www.luogu.com.cn/problem/P2249
    includeusingnamespacestd;intmain(){intp,sum;cin>>p>>sum;intarr[p];for(inti=0;i<p;i++){cin>>arr[i];}for(inti=1;i<=sum;i++){intmubiao;intmin=0;intmax=p-1;cin>>mubiao;for(;;){if(arr[0]mubiao){printf(......
  • 每日总结43
    下载python库缓慢时,可以更改为国内的镜像使用国内镜像源:由于pip默认从PyPI下载,而PyPI的服务器在国外,导致下载速度慢。您可以更换为国内的镜像源来加速下载。以下是几个常用的国内镜像源:清华大学:https://pypi.tuna.tsinghua.edu.cn/simple阿里云:https://mirrors.aliyun.com......
  • 每日打卡 11.13
    includeusingnamespacestd;definemax10voidswap(int*px,int*py);voidbubble(inta[],intn);intmain(){intn,a[max];inti;cout<<"输入n"<<endl;cin>>n;cout<<"输入n个数"<<endl;for(i=0;......
  • 每日新闻掌握【2024年11月12日 星期二】
    2024年11月12日星期二 农历十月十二 大公司/大事件 人形机器人产业链捷报频传,机构指出产业链年底有望迎来定点特斯拉CEO埃隆·马斯克透露,特斯拉正在改进Optimus机器人的设计,以解决生产过程中的关键瓶颈问题,“Optimus已经在工厂里执行一些任务,其能力范围正在迅速扩......
  • 每日新闻掌握【2024年11月11日 星期一】
    2024年11月11日星期一 农历十月十一 大公司/大事件 国产新机上市,老款iPhone跌至半价近期,国产品牌新机先后上市,掀起新一轮换机潮。对于本土品牌新机上新,苹果则面临着巨大市场竞争压力。IDC最新数据显示,2024年第三季度,苹果凭借年度新品的上市,以15.6%的市场份额重返中......
  • 每日总结40
    软件设计                 石家庄铁道大学信息学院 实验9:桥接模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解桥接模式的动机,掌握该模式的结构;2、能够利用桥接模式解决实际问题。    [实验任务一]:两个维度的桥接模......
  • 每日总结39
    软件设计                 石家庄铁道大学信息学院 实验8:适配器模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解适配器模式的动机,掌握该模式的结构;2、能够利用适配器模式解决实际问题。    [实验任务一]:双向适配器......
  • 每日总结38
    软件设计                 石家庄铁道大学信息学院 实验7:单例模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解单例模式的动机,掌握该模式的结构;2、能够利用单列模式解决实际问题。    [实验任务一]:学号的单一仿照......
  • 每日总结41
    软件设计                 石家庄铁道大学信息学院 实验10:组合模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解组合模式的动机,掌握该模式的结构;2、能够利用组合模式解决实际问题。    [实验任务一]:组合模式用透明......