SICP 习题 1.28 要求使用 Miller-Rabin检查来检测素数。
题目中说到Miller-Rabin检查是费马检查的一种变形,不过这种变形不会被Carmichael数欺骗。
上几题搞费马检查都已经苦死我了,现在还来费马检查的变形?变形金刚我就知道,擎天柱我很喜欢,大黄蜂也不错。对着习题1.28回忆了一段童年动画片以后,题目还是摆在那里纹丝不动,于是最终还是硬着头皮去看题目细节。
首先来看看这个变形,前面几道题的费马检查是判断((a的n次方)对n求模)是否等于a,是的话n是素数的可能性就大,而这里所谓的变形就是判断( (a 的(n-1)次方)对n求模)是否等于1,是的话n是素数的可能性就大。
就这个变形我都想了老半天,因为书中对这个变形的描述更加晦涩一些,书中是说“a的(n-1)次幂与1模n同余”,我当时就愣了好久,“与1模n同余”啥意思,1模啥不还是1吗?难道我哪里理解不对?
后来通过其它网上资料验证就是“a的(n-1)次幂对n求模等于1”的意思,搞这么复杂。
明确了这个变形后就简单一些了,因为我们之前已经定义了expmod过程,只需要调用下面的过程就可以计算“a的(n-1)次幂对n求模”了:
(expmod a (- n 1) n)
然后判断它是否等于1就好了。
于是很快修改了我的full-fermat-test过程的代码,注意,是修改了full-fermat-test的代码,就是那个对所有小于n大于1的数进行检查的那个过程,后来证实我这个行为带来了一系列其它问题。
我将代码
(define (fermat-try n a)
(= (expmod a n n ) a))