java 素性测试_在Java中测试primality的最快方法是什么?

这是另一种方式:

boolean isPrime(long n) {

if(n < 2) return false;

if(n == 2 || n == 3) return true;

if(n%2 == 0 || n%3 == 0) return false;

long sqrtN = (long)Math.sqrt(n)+1;

for(long i = 6L; i <= sqrtN; i += 6) {

if(n%(i-1) == 0 || n%(i+1) == 0) return false;

}

return true;

}

并且BigInteger's isProbablePrime(...)对所有32位有效int。

编辑

请注意,isProbablePrime(certainty)并不总是产生正确的答案。当确定性偏低时,会产生误报,如评论中提到的@ dimo414。

不幸的是,我找不到声称isProbablePrime(certainty)对所有(32位)有效的来源int(给定足够的确定性!)。

所以我进行了几次测试。我创建了一个代表所有不均匀数字BitSet的大小,Integer.MAX_VALUE/2并使用主筛来查找范围内的所有素数1..Integer.MAX_VALUE。然后我循环i=1..Integer.MAX_VALUE测试每一个new BigInteger(String.valueOf(i)).isProbablePrime(certainty) == isPrime(i)。

对于确定性5和10,isProbablePrime(...)沿线产生误报。但是isProbablePrime(15),没有测试失败。

这是我的测试台:

import java.math.BigInteger;

import java.util.BitSet;

public class Main {

static BitSet primes;

static boolean isPrime(int p) {

return p > 0 && (p == 2 || (p%2 != 0 && primes.get(p/2)));

}

static void generatePrimesUpTo(int n) {

primes = new BitSet(n/2);

for(int i = 0; i < primes.size(); i++) {

primes.set(i, true);

}

primes.set(0, false);

int stop = (int)Math.sqrt(n) + 1;

int percentageDone = 0, previousPercentageDone = 0;

System.out.println("generating primes...");

long start = System.currentTimeMillis();

for(int i = 0; i <= stop; i++) {

previousPercentageDone = percentageDone;

percentageDone = (int)((i + 1.0) / (stop / 100.0));

if(percentageDone <= 100 && percentageDone != previousPercentageDone) {

System.out.println(percentageDone + "%");

}

if(primes.get(i)) {

int number = (i * 2) + 1;

for(int p = number * 2; p < n; p += number) {

if(p < 0) break; // overflow

if(p%2 == 0) continue;

primes.set(p/2, false);

}

}

}

long elapsed = System.currentTimeMillis() - start;

System.out.println("finished generating primes ~" + (elapsed/1000) + " seconds");

}

private static void test(final int certainty, final int n) {

int percentageDone = 0, previousPercentageDone = 0;

long start = System.currentTimeMillis();

System.out.println("testing isProbablePrime(" + certainty + ") from 1 to " + n);

for(int i = 1; i < n; i++) {

previousPercentageDone = percentageDone;

percentageDone = (int)((i + 1.0) / (n / 100.0));

if(percentageDone <= 100 && percentageDone != previousPercentageDone) {

System.out.println(percentageDone + "%");

}

BigInteger bigInt = new BigInteger(String.valueOf(i));

boolean bigIntSays = bigInt.isProbablePrime(certainty);

if(isPrime(i) != bigIntSays) {

System.out.println("ERROR: isProbablePrime(" + certainty + ") returns "

+ bigIntSays + " for i=" + i + " while it " + (isPrime(i) ? "is" : "isn't" ) +

" a prime");

return;

}

}

long elapsed = System.currentTimeMillis() - start;

System.out.println("finished testing in ~" + ((elapsed/1000)/60) +

" minutes, no false positive or false negative found for isProbablePrime(" + certainty + ")");

}

public static void main(String[] args) {

int certainty = Integer.parseInt(args[0]);

int n = Integer.MAX_VALUE;

generatePrimesUpTo(n);

test(certainty, n);

}

}

我跑的是这样做的:

java -Xmx1024m -cp . Main 15

在我的机器上生成素数大约需要30秒。而所有的实际测试i中1..Integer.MAX_VALUE花了大约2小时15分钟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值