SICP 1.25 解释器问题
SICP 1.25 interpreter issue
1) DrRacket
2) https://inst.eecs.berkeley.edu/~cs61a/sp15/assets/interpreter/scheme.html
将上述两种解释器用于带有参数 (expmod 11 17 17)
的 Hacker 版本会产生不同的答案。 DrRacket 为 11(程序应该如此),inst.eecs.berkeley.edu
为 0
包括在底部的示例评估。在使用 inst.eecs.berkeley.edu 时将所有 (< base m)
替换为两个解释器会产生不同的答案,因此会使该解释器的整个定时素数测试失败。
我的问题:这个解释器的根本问题是什么?这个问题是由于解释错误造成的吗?两者之间的评估方法不同?
(define (expmod base exp m)
(remainder (fast-expt base exp) m))
(define (fast-expt b n)
(cond ((= n 0) 1)
((even? n) (square (fast-expt b (/ n 2))))
(else (* b (fast-expt b (- n 1))))))
(define (even? n)
(= (remainder n 2) 0))
(define (square x)
(* x x))
(remainder (fast-expt 11 17) 17)
(remainder (* 11 (fast-expt 11 16)) 17)
(remainder (* 11 (square (fast-expt 11 8))) 17)
(remainder (* 11 (square (square (fast-expt 11 4)))) 17)
(remainder (* 11 (square (square (square (fast-expt 11 2))))) 17)
(remainder (* 11 (square (square (square (square (fast-expt 11 1)))))) 17)
(remainder (* 11 (square (square (square (square (* 11 (fast-expt 11 0))))))) 17)
(remainder (* 11 (square (square (square (square (* 11 1)))))) 17)
(remainder (* 11 (square (square (square (square 11))))) 17)
(remainder (* 11 (square (square (square 121)))) 17)
(remainder (* 11 (square (square 14641))) 17)
(remainder (* 11 (square 214358881)) 17)
(remainder (* 11 45949729863572161) 17)
(remainder 505447028499293771 17)
一个link到在线SICP
所以虽然 DrRacket 有一个 SICP language SICP 代码应该工作的地方 Racket 的默认语言与 Scheme 不兼容。它很接近,因此这两种语言比 Java 和 C# 有更多共同点,但它们被认为是不同的语言。
Racket 支持 Scheme。 #!r5rs
和 #!r6rs
.
您的在线解释器可能只有基本的 Scheme 功能,也许只有浮点数。只有 R7RS 需要完整的数字塔,因此大数字可能会变成浮点数。我的一个非常简单的测试表明这个数字很快变得不准确:
(/ 1 2) ; ==> 0.5
对于完整的数字塔,答案将是有理数 1/2
。评估call/cc
和exact->inexact
给出了错误,因此解释器不符合标准方案报告的要求。
您需要阅读 chosen implementation 的文档和功能,因为您的程序可能依赖于并非随处可见的功能。如果我实现了一种对某些 Java 绑定具有基本支持的 curly 语言,它仍然不会是 Java 实现,因为它是不完整的。
1) DrRacket
2) https://inst.eecs.berkeley.edu/~cs61a/sp15/assets/interpreter/scheme.html
将上述两种解释器用于带有参数 (expmod 11 17 17)
的 Hacker 版本会产生不同的答案。 DrRacket 为 11(程序应该如此),inst.eecs.berkeley.edu
包括在底部的示例评估。在使用 inst.eecs.berkeley.edu 时将所有 (< base m)
替换为两个解释器会产生不同的答案,因此会使该解释器的整个定时素数测试失败。
我的问题:这个解释器的根本问题是什么?这个问题是由于解释错误造成的吗?两者之间的评估方法不同?
(define (expmod base exp m)
(remainder (fast-expt base exp) m))
(define (fast-expt b n)
(cond ((= n 0) 1)
((even? n) (square (fast-expt b (/ n 2))))
(else (* b (fast-expt b (- n 1))))))
(define (even? n)
(= (remainder n 2) 0))
(define (square x)
(* x x))
(remainder (fast-expt 11 17) 17)
(remainder (* 11 (fast-expt 11 16)) 17)
(remainder (* 11 (square (fast-expt 11 8))) 17)
(remainder (* 11 (square (square (fast-expt 11 4)))) 17)
(remainder (* 11 (square (square (square (fast-expt 11 2))))) 17)
(remainder (* 11 (square (square (square (square (fast-expt 11 1)))))) 17)
(remainder (* 11 (square (square (square (square (* 11 (fast-expt 11 0))))))) 17)
(remainder (* 11 (square (square (square (square (* 11 1)))))) 17)
(remainder (* 11 (square (square (square (square 11))))) 17)
(remainder (* 11 (square (square (square 121)))) 17)
(remainder (* 11 (square (square 14641))) 17)
(remainder (* 11 (square 214358881)) 17)
(remainder (* 11 45949729863572161) 17)
(remainder 505447028499293771 17)
一个link到在线SICP
所以虽然 DrRacket 有一个 SICP language SICP 代码应该工作的地方 Racket 的默认语言与 Scheme 不兼容。它很接近,因此这两种语言比 Java 和 C# 有更多共同点,但它们被认为是不同的语言。
Racket 支持 Scheme。 #!r5rs
和 #!r6rs
.
您的在线解释器可能只有基本的 Scheme 功能,也许只有浮点数。只有 R7RS 需要完整的数字塔,因此大数字可能会变成浮点数。我的一个非常简单的测试表明这个数字很快变得不准确:
(/ 1 2) ; ==> 0.5
对于完整的数字塔,答案将是有理数 1/2
。评估call/cc
和exact->inexact
给出了错误,因此解释器不符合标准方案报告的要求。
您需要阅读 chosen implementation 的文档和功能,因为您的程序可能依赖于并非随处可见的功能。如果我实现了一种对某些 Java 绑定具有基本支持的 curly 语言,它仍然不会是 Java 实现,因为它是不完整的。