目录
Miller-Rabin Primality Test(米勒-罗宾随机素性测试)
Miller-Rabin Primality Test(米勒-罗宾随机素性测试)
静态素数证据表实现(非随机数实现)
函数MillerRabin(LL n, LL a)为一次米勒-罗宾测试结果,true表示测试数n有3/4的把握为素数,false表示n一定是合数。
调用bool isPrime(LL n)来判断数n是否为素数。
bool isPrime(LL n)中的素数表可根据需要增加或减少,增加素数表会使测试的准确率升高,但是测试时间会增长。
#include <iostream>
using namespace std;
typedef long long LL;
LL fastPowMod(LL base, LL p, LL mod) {
LL ret = 1;
base %= mod;
do {
if (p & 1) ret = ret * base % mod;
base = base * base % mod;
} while (p >>= 1);
return ret;
}
// true: prime a is evidence of "n is prime"
bool MillerRabin(LL n, LL a) {
if (n == 2 || n == a) return true;
if (!(n & 1)) return false;
LL q = n - 1, cnt = 0;
while (!(q & 1)) q >>= 1, cnt++;
LL tmp = fastPowMod(a, q, n);
if (tmp == 1) return true;
for (LL i = 0; i < cnt; i++, tmp = tmp * tmp % n)
if (tmp == n - 1) return true;
return false;
}
bool isPrime(LL n) {
if (n < 2) return false;
else if (n == 2) return true;
LL p[] = {2, 3, 13, 61, 127, 4013, 9973};
for (LL i = 0; i < 7; i++)
if (!MillerRabin(n, p[i])) return false;
return true;
}
int main(void) {
for (LL i = 1; i <= 100; i++) {
cout << i << " is Prime ? " << (isPrime(i) ? "YES" : "NO") << "\n";
}
// 561是合数,是一个卡米歇尔数(强伪素数)
cout << 561 << " is Prime ? " << (isPrime(561) ? "YES" : "NO") << "\n";
return 0;
}
Time Complexity: O(log n)
依赖:
-整数快速模幂(逐次平方法)
使用Java大数类判断素数
使用BigInteger类的isProbablePrime方法可以进行素性测试。
public boolean isProbablePrime(int certainty) |
其中certainly表示确信程度,如果返回false,可以断言这个数不是素数,而如果返回true,这个数将有(1 – 1 / 2^certainly)的概率可能是素数,这个参数将会影响此方法所占用的时间。
生成可能素数的方法:
public static BigInteger probablePrime(int bitLength, Random rnd) |
其中bitlength表示生成素数的二进制位数上限,应当不小于2,Random用来生成随机数来进行素性测试。
寻找下一个素数的方法:
public BigInteger nextProbablePrime() |
此方法保证寻找到的下一个素数与当前素数之间不存在其它任何素数。
示例程序:
import java.math.BigInteger;
import java.util.Random;
public class Main {
public static void main(String[] args) {
BigInteger tmp = new BigInteger("1000000007");
System.out.println(tmp.isProbablePrime(5) ? "Yes" : "No");
BigInteger prime = BigInteger.probablePrime(5, new Random());
System.out.println(prime);
System.out.println("next is: " + prime.nextProbablePrime());
}
}