【发布时间】:2019-09-21 23:15:56
【问题描述】:
SICP 练习 1.28
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-11.html#%_thm_1.28
费马检验的一种变体,不能被愚弄 称为 Miller-Rabin 检验(Miller 1976;Rabin 1980)。这开始 来自费马小定理的另一种形式,它指出 如果 n 是素数并且 a 是小于 n 的任何正整数,则 a 的 (n - 1) 次幂等于 1 模 n。去测试 通过米勒-拉宾检验,我们随机选择一个数 n 的素数 数字 a 如果n是一个非素数的奇数,那么, 对于至少一半的数字 a (这就是为什么 Miller-Rabin 测试不能被愚弄。)将 expmod 过程修改为 如果它发现一个非平凡的平方根 1,则发出信号,并使用它来 使用类似于 费马测试。通过测试各种已知的素数和 非素数。提示:制作 expmod 信号的一种方便方法是 它返回 0。
我已经编写了自己的解决方案,其结果与此处提供的解决方案一致:
http://community.schemewiki.org/?sicp-ex-1.28
15 是一个非素数的奇数,因此对于从1 到14 的至少一半数字a,我预计计算expmod(a, 14, 15) 将显示一个模数为n 的非平凡平方根,由expmod返回0表示。
但是,这些是我得到的结果:
(expmod 1 14 15)
> 1
(expmod 2 14 15)
> 4
(expmod 3 14 15)
> 9
(expmod 4 14 15)
> 0
(expmod 5 14 15)
> 10
(expmod 6 14 15)
> 6
(expmod 7 14 15)
> 4
(expmod 8 14 15)
> 4
(expmod 9 14 15)
> 6
(expmod 10 14 15)
> 10
(expmod 11 14 15)
> 0
(expmod 12 14 15)
> 9
(expmod 13 14 15)
> 4
(expmod 14 14 15)
> 1
可以看出,这些结果中只有 2 个是 0,与预期的至少 7 个相比相差甚远。
我误解了声明吗?我是一个彻头彻尾的白痴吗?代码错了吗? SICP错了吗?非常感谢。
编辑 1:要求我提供我正在使用的确切代码。就是这样,虽然我基本上只是复制了我链接到的解决方案,并将 remainder 别名为 mod 因为这是我的解释器所说的。
(define (square x) (* x x))
(define remainder mod)
(define (miller-rabin-expmod base exp m)
(define (squaremod-with-check x)
(define (check-nontrivial-sqrt1 x square)
(if (and (= square 1)
(not (= x 1))
(not (= x (- m 1))))
0
square))
(check-nontrivial-sqrt1 x (remainder (square x) m)))
(cond ((= exp 0) 1)
((even? exp) (squaremod-with-check
(miller-rabin-expmod base (/ exp 2) m)))
(else
(remainder (* base (miller-rabin-expmod base (- exp 1) m))
m))))
(define expmod miller-rabin-expmod)
(print (expmod 1 14 15))
(print (expmod 2 14 15))
(print (expmod 3 14 15))
(print (expmod 4 14 15))
(print (expmod 5 14 15))
(print (expmod 6 14 15))
(print (expmod 7 14 15))
(print (expmod 8 14 15))
(print (expmod 9 14 15))
(print (expmod 10 14 15))
(print (expmod 11 14 15))
(print (expmod 12 14 15))
(print (expmod 13 14 15))
(print (expmod 14 14 15))
编辑 2:我现在还手动计算了 expmod(a, 14, 15) 的步骤(它总是通过 exp = 14、exp = 7、exp = 6、exp = 3、exp = 3、exp = 2、exp = 1、exp = 0 递归),对于从 1 到 14 的 a 的所有值,我确信只有 a = 4 和 a = 11 遇到 1 的非平凡平方根。所以我倾向于认为 SICP 对此要么是错误的,或者表达不清晰。
【问题讨论】:
-
您对 expmod 过程的修改很可能存在错误。
-
@JamesKPolk 我没有修改它,我使用了我链接的解决方案中的代码,并且我也使用了我自己的版本,并且它们彼此一致。如果您认为我使用不正确,请检查我自己链接的解决方案。
-
抱歉,它被读作 a^(n-1),而不是 a^n - 1(按照我链接的 SICP 文本中的格式;我将编辑我的问题)——基本上是检查费马小定理。
标签: scheme primes sicp primality-test