1. 程式人生 > 實用技巧 >快速素數測試(Miller-Robin)

快速素數測試(Miller-Robin)

ll fm(ll x,ll y,ll mod){
    ll ans=0;
    while(y>0){
        if(y&1)ans=(ans+x)%mod;
        y>>=1;
        x=(x+x)%mod;
    }
    return ans;
}
ll fp(ll b,ll p,ll mod){
    ll ans=1;
    while(p){
        if(p&1)ans=ans*b%mod;
        p>>=1;
        b=b*b%mod;
    }
    return ans;
}
int strong_pseudo_primetest(ll n, int base) {
    ll n2 = n - 1, res;
    int s = 0;
    while (n2 % 2 == 0) n2 >>= 1, s++;
    res = fp(base, n2, n);
    if ((res == 1) || (res == n - 1)) return 1;
    s--;
    while (s >= 0) {
        res = fm(res, res, n);
        if (res == n - 1) return 1;
        s--;
    }
    return 0;// n is not a strong pseudo prime
}
int isprime(ll n) {
    static ll testNum[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
    static ll lim[] = {4, 0, 1373653ll, 25326001ll,25000000000ll, 2152302898747ll, 3474749660383ll, 341550071728321ll,0, 0, 0, 0};
    if (n < 2 || n == 3215031751ll) return 0;
    for (int i = 0; i < 12; ++i) {
        if (n < lim[i]) return 1;
        if (strong_pseudo_primetest(n, testNum[i]) == 0) return 0;
    }
    return 1;
}