判断一个正整数是否为质数的算法(第二周作业2.1)

来源:互联网 发布:模拟编程软件 编辑:程序博客网 时间:2024/06/06 19:28

使用Miller-Rabin素性测试来判断一个数是否为素数

源代码如下:

public static int isPrime(long a){for(int i=0;i<100;i++){//u的取值范围为1<u<a,本算法是Miller-Rabin素性检测,如果u=1,将会使得所有的a对于u^(a-1)=1(mod a)都成立long  u=(long)Math.floor(Math.random()*(a-2)+2);if (runFermat(u, a-1, a)==1){//根据二次探测定理:如果p是素数,且0<x<p,则方程x*x=1(mod p)的解为x=1,p-1;if ((u*u)%a==1&&u!=1&&u!=a-1){return 0;}}else {return 0;}}return 1;}//大数模幂快速算法/***return:(a^b)mod n**/        public static long runFermat(long a,long b,long n)        {           long result=1;           while (b>0)           {               if ((b&1)==1)               {                   result=(result*a)%n;               }               a=(a*a)%n;               b=b>>1;            }           return result;        }

    这段代码中有两个函数isPrime(long a)是判断一个数是否为素数的函数,它是基于费马小定理的一个概率函数,即该函数会出现误判的结果。

     费马小定理:如果p是一个素数,那么对于任意1<=a<p,有a^(p-1)=1(mod p).

     但是费马小定理不是判断一个数是否为素数的充要条件。对于N不是素数,抽取一个a<N,通过费马小定理的概率<1/2。程序中使用了for循环进行了100次素性测试,所以该程序出现误判的概率为(1/2)^100.该概率是一个极小的数。

   另一个函数runFermat(long a,long b,long n)是计算费马小定理时的模幂运算。如果使用Java的Math.pow()函数计算a^b,由于Math.pow()返回的是double,最后求模时需要整型,double转整型会丢失精确度。该函数使用了大数模幂快速算法,使用大数模幂快速算法,不仅可以避免计算a^b是出现溢出,而且可以降低计算a^b的时间复杂度度。

 

0 0