奇怪的 mit-scheme 解释器行为

Strange mit-scheme interpreter behaviour

开始研究SICP,用repl.it做代码练习。现在我想在本地编写代码。我已经安装了 mit-scheme 应用程序并尝试将我的代码从 repl.it 移动到我的计算机。

但是当我尝试 运行 计算平方根的程序时,我得到了非常奇怪的输出,结果是非常大的数字:

1 ]=> (define (square x) (* x x))
;Value: square

1 ]=> (define (abs x) (if (<= x 0) (- x) x))
;Value: abs

1 ]=> (define (average x y) (/ (+ x y) 2))
;Value: average

1 ]=> (define (improve guess x) (average guess (/ x guess)))
;Value: improve

1 ]=> (define (good-enough? new_guess old_guess)
    (< (abs (- new_guess old_guess)) 0.000000000000001))
;Value: good-enough?

1 ]=> (define (sqrt-iter guess x)
    (define new_guess (improve guess x))
    (if (good-enough? new_guess guess)
        new_guess
        (sqrt-iter new_guess x)))
;Value: sqrt-iter

1 ]=> (define (sqrt x) (sqrt-iter 1 x))
;Value: sqrt

1 ]=> (sqrt 16)
;Value: 271050543121377825343773346473727756780989953/67762635780343597914988263490310774732975168

1 ]=> 
End of input stream reached.

这是程序的源代码,它在 repl.it:

(define (square x) (* x x))

(define (abs x)
  (if (<= x 0) (- x) x))

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

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

(define (good-enough? new_guess old_guess)
  (< (abs (- new_guess old_guess)) 0.000000000000001))

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

(define (sqrt x) (sqrt-iter 1 x))

(sqrt 16)

注意: OS: MacOS Catalina, mit-scheme 应用程序版本 - 10.1.11

我该如何修复这个错误?

这不是一个大数字,实际上它只是一个接近 4.0 的有理数,仔细看一下(为了清楚起见,我添加了额外的空格):

271050543121377825343773346473727756780989953 / 67762635780343597914988263490310774732975168

您将通过切换到不精确的算术得到想要的结果,只需将您的初始 guess 设置为十进制值:

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

现在它按预期工作了:

(sqrt 16)
=> 4.0

请参阅经典文章 What Every Computer Scientist Should Know About Floating-Point Arithmetic 以了解有关为什么 发生这种情况的更多详细信息。

这在方案中称为强制

您需要阅读有关 泛型函数 的章节以了解强制转换的工作原理。