素数判定 费马測试


;; Fermat's Little Theorem:

;; If N is a prime number and A is any positive integer less than N, 

;; then A raised to the N-th power is congruent to A modulo N


;; Two numbers are said to be congruent modulo N if they both
;; have the same remainder when divided by N


;; The Fermat test:
;; Given a number N, pick a random number A < N
;; and compute the remainder of A^N modulo N.
;; If the result is not equal to A, then N is certainly not prime
;; If it is A, then chances are good that N is prime.
;; Now pick anthor random number A and test it with the same method.
;; If it also satisfies the equation,
;; then we can be even more confident that N is prime.
;; By trying more and more values of A,
;; We can increase our confidence in the result.
;; This algorithm is known as the Fermat test.



( define ( bad-exp base exp )

( cond  ( ( = exp 0 ) 1 )

( ( even?

exp )

( square ( bad-exp base ( / exp 2 ) ) ) )

( else ( * base ( bad-exp base ( - exp 1 ) ) ) ) ) )



( define ( bad-expmod base exp m )

( remainder ( bad-exp 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 ) ) ) )



;; 第一个过程比第二个过程慢,且超过一定长度的数值就不能计算,
;; 由于第一个是先将阶乘算出来。再取模,而第二个是在阶乘的过程中就取模
;; 26 mod 4 和 ( 2 mod 4 ) * ( 13 mod 4 ) 结果一样
;; ( expmod 32 10911110033 10911110033 )
;; ( my-expmod 32 1091111003 1091111003 )



( define ( fermat-test n )

( define ( try-it a )

( = ( expmod a n n ) a ) )

( try-it ( + 1 ( random ( - n 1 ) ) ) ) )



( define ( fast-prime? n times )

( cond  ( ( = times 0 ) true )

( ( fermat-test n ) 

( fast-prime? n ( - times 1 ) ) )

( else false ) ) )




;; The Fermat test differs in character from most familiar algorithms, 
;; in which one computes an answer that is guaranteed to be correct. 
;; Here, the answer obtained is only probably correct. 
;; More precisely, if N ever fails the Fermat test,
;; we can be certain that N is not prime. 
;; But the fact that N passes the test, 
;; while an extremely strong indication, 
;; is still not a guarantee that N is prime. 
;; What we would like to say is that for any number N, 
;; if we perform the test enough times and find that N always passes the test, 
;; then the probability of error in our primality test can be made as small as we like.


;; Unfortunately, this assertion is not quite correct. 
;; There do exist numbers that fool the Fermat test: 
;; numbers N that are not prime and yet have the property that
;; an is congruent to a modulo n for all integers A < N.
;; Such numbers are extremely rare, 
;; so the Fermat test is quite reliable in practice


;; There are variations of the Fermat test that cannot be fooled. 
;; In these tests, as with the Fermat method,
;; one tests the primality of an integer N
;; by choosing a random integer A < N and 
;; checking some condition that depends upon N and A.


;; On the other hand, in contrast to the Fermat test, 
;; one can prove that, for any N, 
;; the condition does not hold for most of the integers A < N
;; unless N is prime. 
;; Thus, if N passes the test for some random choice of A, 
;; the chances are better than even that N is prime.
;; If N passes the test for two random choices of A, 
;; the chances are better than 3 out of 4 that N is prime. 
;; By running the test with more and more randomly chosen
;; values of A we can make the probability of error as small as we like.
;; The existence of tests for which one can prove that 
;; the chance of error becomes arbitrarily small has sparked interest in 
;; algorithms of this type, 
;; which have come to be known as probabilistic algorithms.
;; There is a great deal of research activity in this area,
;; and probabilistic algorithms have been
fruitfully applied to many fields

原文地址:https://www.cnblogs.com/zfyouxi/p/5251768.html