Miller-Rabin素性判定算法

Posted plumlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Miller-Rabin素性判定算法相关的知识,希望对你有一定的参考价值。

Miller-Rabin素性判定算法是一种基于概率的判定算法,每次判定n是素数的正确性概率至少为75%,出错的概率小于25%。

如果对n进行k次素性检测,如果结果n为素数,那么n为合数的概率为1/(4^k)。如果k足够大,那么误判的概率就非常小。

算法原理如下:

技术图片

 

#include <iostream>
#include <random>
#include <time.h>
using namespace std;
typedef unsigned __int64 llong;//无符号64位整形
//typedef为已有的类型起一个别名。
//既然是别名,对同一类型可以起多个别名。这在C/C++中是允许的,各个别名和真名的作用都是一样有效的。

llong mod_pro(llong x,llong y,llong n)
{
    llong ret=0,tmp=x%n;
    while(y)
    {
        if(y&0x1)
            if((ret+=tmp)>n)
                ret-=n;
        if((tmp<<=1)>n)
            tmp-=n;
        y>>=1;//>>= 意思为:右移后赋值(按位移)
    }
    return ret;

}


//a^b mod c
llong mod(llong a,llong b,llong c)//a:原理中的b,b:m,c:n
{
    llong ret=1;
    while(b)
    {
        if(b&0x1)//b不为偶数
            ret=mod_pro(ret,a,c);//1,随机数,n
        a=mod_pro(a,a,c);
        b>>=1;
    }
    return ret;
}

llong ran()
{
    llong ret =rand();
    return ret*rand();
}

bool is_prime(llong n,int t)//轮数为3
{
    if(n<2)
        return false;
    if(n==2)
        return true;
    if(!(n&0x1))//按位与运算(为偶数)
        return false;
    llong k=0,m,a,i;
    for(m=n-1; !(m&1); m>>=1,k++);// !(m&1):m是偶数
    cout<<m<<" "<<k<<endl;//m是m,k是s:n-1= 2^s*m

    while(t--)
    {
        a=mod(ran()%(n-2)+2,m,n);//ran()%(n-2)+2:随机整数b
        if(a!=1)//圈3
        {
            for(i=0; i<k&&a!=n-1; i++)
            {
                a=mod_pro(a,a,n);
            }
            if(i>=k)
                return false;
        }
    }
    return true;
}


int main()
{

    llong n;
    cout<<"请输入一个大于三的整数:";
    while(scanf("%I64u",&n)!=EOF)//__int64结构的输入格式
    {
        clockid_t starttime,endtime;
        starttime=clock();

        if(is_prime(n,3))
            cout<<"YES
";
        else
            cout<<"NO
";
        endtime=clock();
        cout<<"用时"<<endtime-starttime<<"毫秒
"<<endl;
        cout<<"请输入一个大于三的整数:";
    }
    return 0;
}

 

 

 学到了:

  • typedef 的用法:typedef为已有的类型起一个别名,同一个类型可以有多个别名,在该例子中把 unsigned __int64 起名为llong 方便引用
  •     unsigned __int64 无符号64位整形类型
  •     >>= 意思为:右移后赋值(按位移)
  •     (n&0x1))//n和十六进制的1按位与运算(为偶数)

 

以上是关于Miller-Rabin素性判定算法的主要内容,如果未能解决你的问题,请参考以下文章

hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测

记一次使用快速幂与Miller-Rabin的大素数生成算法

Miller-Rabin素数测试

关于Miller-Rabin素性测试,高手进

Miller-Rabin素性测试(Python实现)

Miller-Rabin 素性测试