我正在尝试解决SICP中有关Miller-Rabin算法的练习1.28,此后我在网上找到了答案,但我认为答案是错误的。我来问是否有问题。
他在执行expmod循环时检查是否(remainder (square base) m)=1
。但是,执行循环时,基数和m会保持不变,这意味着他正在执行相同的检查,这不是Miller-Rabin检验想要做的。
(define (expmod base exp m)
(cond ((= exp 0)
1)
((nontrivial-square-root? base m)
0)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
(define (nontrivial-square-root? a n)
(and (not (= a 1))
(not (= a (- n 1)))
(= 1 (remainder (square a) n))))
如果n=k*2^c
,我认为我们应该检查(remainder (a^(k*2*(c-1))) n)=1
。
答案 0 :(得分:1)
这就是应该做的。过程expmod
应该计算一个以另一个数为模的数字的指数,这次的唯一区别是,每次递归时都要检查一个平凡的平方根。 m
将在expmod
过程中保持不变,并且您编写的miller-rabin
过程将每次以随机数expmod
运行m
。
编码愉快!
顺便说一下,SICP祝您好运!我现在正在练习2.45,它变得更容易(尽管有一些非常抽象的概念)。