如何解决SICP练习1.17问题
我正在SICP中进行练习1.18,遇到一些麻烦。目的是根据之前的两个练习制定一个程序。此过程执行所谓的俄罗斯农民方法(或古埃及乘法)。我写了一个代码,但是一个过程只是不想执行。这是我的代码:
#lang sicp
(define (double a) (+ a a))
(define (halve a) (/ a 2))
(define (r_m a b)
(iter a b 0))
(define (iter a b n)
(cond ((= b 0) 0)
((even? a) (iter (halve a) (double b) (+ n b)))
(else (iter (halve a) (double b) n))))
因此,当我使用(r_m)
这样的参数调用过程(r_m 13 19)
时,它将在第一次迭代后停止。
(iter (halve a) (double b) (+ n b)
(带有参数13和19)给出以下结果:iter (13/2) 38 19
然后,程序尝试检查13/2是否为奇数。但是它无法检查这样的数字(13/2),因为odd?
需要一个整数,而不是这个未完成的除法。
由于某些原因,halve
过程在调用时不起作用。我真的不明白为什么,因为其他过程(double
和简单的+ n b
)都可以正常工作。
预先感谢您,希望我的语法不会对您造成太大伤害。
解决方法
程序有几处错误。除了其他方面,即使halve
以您希望的方式工作,b
怎么会变成零?这不是唯一的问题!
但是发生halve
的特殊情况是因为您假设编程语言可以执行它们通常的工作:对机器方便的错误算术,而不是对人类方便的正确算术。 Scheme努力进行正确运算。数学上,13/2是多少?不是6或7或3,而是13/2或6 + 1/2:这是一个有理数,而不是整数。
如果要使下一个整数小于13/2,则要得到的方式是在除以之前将1减去:(一半(-13 1))等于6。因此,如果将cond
子句更改为具有(halve (- a 1))
,您的程序将更接近工作了(但是实际上,它随后将无法终止,因此从某种意义上说,它将进一步远离工作... )。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。