奇怪的 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 以了解有关为什么 发生这种情况的更多详细信息。
这在方案中称为强制。
您需要阅读有关 泛型函数 的章节以了解强制转换的工作原理。
开始研究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 以了解有关为什么 发生这种情况的更多详细信息。
这在方案中称为强制。
您需要阅读有关 泛型函数 的章节以了解强制转换的工作原理。