Exercise 1.25. Alyssa P. Hacker complains that we went to a lot of extra work in writing expmod. After all, she says, since we already know how to compute exponentials, we could have simply written
(define (expmod base exp m) (remainder (fast-expt base exp) m))
Is she correct? Would this procedure serve as well for our fast prime tester? Explain.
对比之前的版本
(define (expmod base exp m)
(remainder (fast-expt base exp) m))
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
我们可以看出,只有一个语句的版本是全部算出 exp 次方的值之后再去进行 remainder 操作,而后一个版本,每次计算的都是比较小的值(因为每次递归返回的时候,都只是 remainder 的值,都小于 m。
我们现在用 Fermat 方法来测试 100000001 是否是素数,来验证一下这个想法。
使用第一种方法,假设,随机生成了一个小于该数的数为 99999999。那么我们就要求
(remainder
(fast-expt 99999999 100000001)
100000001)
我们就需要求出