素数判断

判断一个素是否为素数是一个重要的问题,当数很大时还没有好的算法.下面是一个概率算法,基于Fermat小定理.

Fermat小定理: 如果p是一个素数,(a,p)=1,那么ap-1≡1(mod p).

反之则不成立,不过不成立的情况很少.这样的合数称为Carmichael数,第一个Carmichael数为561.在一亿以内只有255个Carmichael数.

可以用Fermat小定理反复探测加上下面的二次探测定理来降低误判的可能性.

二次探测定理: 如果p是素数, 0<x<p,那么方程x2≡1(mod p)的解为x=1或p-1.

下面是代码:

 1 #include<iostream.h>
 2 #include<stdlib.h>
 3 
 4 //求幂同时二次探测
 5 int fermatTest(int a, int p, int n)
 6 {
 7     if (!p)
 8         return 1;
 9     
10     int x = fermatTest(a, p/2, n);
11     int result = x*x % n;
12     if (result == 1 && x != 1 && x != n-1)
13         result = 0;
14     if (p % 2 == 1)
15         result = result * a % n;
16 
17     return result;
18 }
19 
20 //判断是否为素数
21 bool isPrime(int n)
22 {
23     int times = 1;
24 loop: //多次探测
25 
26     int a = rand() % (n-3) + 2; // [2,n-1)
27     if (fermatTest(a, n-1, n) != 1)
28         return false;
29 
30     if (++times > 10) //探测10次
31         goto loop;
32 
33     return true;
34 }
35 
36 void main()
37 {
38     if (isPrime(89))
39         cout<<"Yes.\n";
40 }

posted on 2012-09-20 20:58  赛欧拉  阅读(142)  评论(0)    收藏  举报