Miller_Rabbin

Miller_Rabbin 算法进行素数测试

说明:

速度快,而且可以判断 <2^63的数

复杂度:O(logN) * 测试次数 由于要处理long long,所以略慢

是素数返回true 合数返回false;

使用方法:

  • bool isPrime = Miller_Rabbin(x)

Tips:

  • 需要stdlib.h头文件
  • 可能是伪素数,但概率极小
const int S = 20; //随机算法判定次数,S越大,判错概率越小
ll mult_mod(ll a,ll b,ll mod){
    return (a*b-(ll)(a/(long double)mod*b+1e-3)*mod+mod)%mod;
}

//计算  x^n %c
ll pow_mod(ll x, ll n, ll mod) { //x^n%c
    if(n == 1)return x % mod;
    x %= mod;
    ll tmp = x;
    ll ret = 1;
    while(n) {
        if(n & 1) ret = mult_mod(ret, tmp, mod);
        tmp = mult_mod(tmp, tmp, mod);
        n >>= 1;
    }
    return ret;
}

//以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
//一定是合数返回true,不一定返回false
bool check(ll a, ll n, ll x, ll t) {
    ll ret = pow_mod(a, x, n);
    ll last = ret;
    for(int i = 1; i <= t; i++) {
        ret = mult_mod(ret, ret, n);
        if(ret == 1 && last != 1 && last != n - 1) return true; //合数
        last = ret;
    }
    if(ret != 1) return true;
    return false;
}

// Miller_Rabin()算法素数判定
//
bool Miller_Rabbin(ll n) {
    if(n < 2)return false;
    if(n == 2)return true;
    if((n & 1) == 0) return false; //偶数
    ll x = n - 1;
    ll t = 0;
    while((x & 1) == 0) {
        x >>= 1;
        t++;
    }
    for(int i = 0; i < S; i++) {
        ll a = rand() % (n - 1) + 1; //rand()需要stdlib.h头文件
        if(check(a, n, x, t))
            return false;//合数
    }
    return true;
}

results matching ""

    No results matching ""