给出1个正整数N,检测N是否为质数。如果是,输出"Yes",否则输出"No"。
Input
输入一个数N(2 <= N <= 10^30)
Output
如果N为质数,输出"Yes",否则输出"No"。
Input示例
17
Output示例
Yes
import java.math.BigInteger;
import java.util.Scanner;
public class Bigshu {
public static void main(String[] args)
{
Scanner cin = new Scanner(System.in);
BigInteger x;
x = cin.nextBigInteger();
if(x.isProbablePrime(1))
System.out.println("Yes");
else
System.out.println("No");
}
}
.isProbablePrime(int certainty):如果该 BigInteger 可能是素数,则返回 true ;如果它很明确是一个合数,则返回 false 。 参数 certainty 是对调用者愿意忍受的不确定性的度量:如果该数是素数的概率超过了 1 - 1/2*certainty方法,则该方法返回 true 。执行时间正比于参数确定性的值。
java中的isProbablePrime函数是针对BigInteger类的一个素数判断函数,它的实现原理其实并不复杂,只是要分许多情况讨论,要用到Miller-Rabin素数测试和Lucas-Lehmer测试,它是一个概率算法,返回的结果:一个数不是素数或者一个数可能是素数。下面是它在jdk1.6 src中的主要源代码:
public boolean isProbablePrime(int certainty) {
if (certainty <= 0)
return true;
BigInteger w = this.abs();
if (w.equals(TWO))
return true;
if (!w.testBit(0) || w.equals(ONE))
return false;
return w.primeToCertainty(certainty, null);
}
public boolean testBit(int n) {
if (n < 0)
throw new ArithmeticException("Negative bit address");
return (getInt(n >>> 5) & (1 << (n & 31))) != 0;
}
private int getInt(int n) {
if (n < 0)
return 0;
if (n >= mag.length)
return signInt();
int magInt = mag[mag.length-n-1];
return (signum >= 0 ? magInt :
(n <= firstNonzeroIntNum() ? -magInt : ~magInt));
}
boolean primeToCertainty(int certainty, Random random) {
int rounds = 0;
int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;
// The relationship between the certainty and the number of rounds
// we perform is given in the draft standard ANSI X9.80, "PRIME
// NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".
int sizeInBits = this.bitLength();
if (sizeInBits < 100) {
rounds = 50;
rounds = n < rounds ? n : rounds;
return passesMillerRabin(rounds, random);
}
if (sizeInBits < 256) {
rounds = 27;
} else if (sizeInBits < 512) {
rounds = 15;
} else if (sizeInBits < 768) {
rounds = 8;
} else if (sizeInBits < 1024) {
rounds = 4;
} else {
rounds = 2;
}
rounds = n < rounds ? n : rounds;
return passesMillerRabin(rounds, random) && passesLucasLehmer();
}