素数判断
判断一个素是否为素数是一个重要的问题,当数很大时还没有好的算法.下面是一个概率算法,基于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 }
浙公网安备 33010602011771号