我想使用BigInteger的nextProbablePrime()方法来获得低于给定数字而不是更高的素数.
是否可以使用一个nextProbablePrime调用来获取它?
最佳答案 我不知道是否可以使用nextProbablePrime方法(在一次调用中).但是,我只需要一个previousProbablePrime方法,并且我想出了以下使用BigInteger API中的isProbablePrime方法的方法:
public static BigInteger previousProbablePrime(BigInteger val) {
// To achieve the same degree of certainty as the nextProbablePrime
// method, use x = 100 --> 2^(-100) == (0.5)^100.
int certainty = 100;
do {
val = val.subtract(BigInteger.ONE);
} while (!val.isProbablePrime(certainty));
return val;
}
我设置以下测试只是为了比较nextProbablePrime方法的速度(和准确性):
private static void testPreviousProbablePrime() {
BigInteger min = BigInteger.ONE; // exclusive
BigInteger max = BigInteger.valueOf(1000000); // exclusive
BigInteger val;
// Create a list of prime numbers in the range given by min and max
// using previousProbablePrime method.
ArrayList<BigInteger> listPrev = new ArrayList<BigInteger>();
Stopwatch sw = new Stopwatch();
sw.start();
val = BigIntegerUtils.previousProbablePrime(max);
while (val.compareTo(min) > 0) {
listPrev.add(val);
val = BigIntegerUtils.previousProbablePrime(val);
}
sw.stop();
System.out.println("listPrev = " + listPrev.toString());
System.out.println("number of items in list = " + listPrev.size());
System.out.println("previousProbablePrime time = " + sw.getHrMinSecMsElapsed());
System.out.println();
// Create a list of prime numbers in the range given by min and max
// using nextProbablePrime method.
ArrayList<BigInteger> listNext = new ArrayList<BigInteger>();
sw.reset();
sw.start();
val = min.nextProbablePrime();
while (val.compareTo(max) < 0) {
listNext.add(val);
val = val.nextProbablePrime();
}
sw.stop();
System.out.println("listNext = " + listNext.toString());
System.out.println("number of items in list = " + listNext.size());
System.out.println("nextProbablePrime time = " + sw.getHrMinSecMsElapsed());
System.out.println();
// Compare the two lists.
boolean identical = true;
int lastIndex = listPrev.size() - 1;
for (int i = 0; i <= lastIndex; i++) {
int j = lastIndex - i;
if (listPrev.get(j).compareTo(listNext.get(i)) != 0) {
identical = false;
break;
}
}
System.out.println("Lists are identical? " + identical);
}
Stopwatch类只是一个跟踪执行时间的基本自定义类,因此修改这些部分以适合您可能具有的类.
我测试了范围从1到10000,100000和1000000. previousProbablePrime方法在所有三个测试中执行时间更长.然而,似乎执行时间的差异仅随着范围大小每增加10倍而适度增加.对于10000,previousProbablePrime在不到一秒的时间内执行,而nextProbablePrime在大约200毫秒内执行,差异大约为700或800毫秒.对于1000000,差异仅为大约2秒,即使执行时间分别为9秒和7秒.结论,执行时间的差异增加慢于范围大小.
在所有测试中,两个列表包含相同的素数集.
这种效率水平足以满足我的需求……也可能对你有用.