import java.math.BigInteger;
public class TwentyDigitPrimes {
public static void main(String[] args) {
// Smallest 20-digit number: 10^19
BigInteger min20Digit = BigInteger.TEN.pow(19);
// Largest 20-digit number: 10^20 - 1
BigInteger max20Digit = BigInteger.TEN.pow(20).subtract(BigInteger.ONE);
// Find boundary 20-digit primes
BigInteger firstPrime = findFirstPrime(min20Digit);
BigInteger lastPrime = findLastPrime(max20Digit);
// Display results
System.out.println("First 20-digit prime: " + firstPrime);
System.out.println("Last 20-digit prime: " + lastPrime);
}
/**
* Finds the smallest prime number with at least 20 digits, starting at 10^19.
*
* @param start Lower bound (10^19)
* @return The first 20-digit prime number
*/
public static BigInteger findFirstPrime(BigInteger start) {
// BigInteger.nextProbablePrime() finds the smallest probable prime strictly greater than 'start'.
// To include 'start' itself if it were prime, subtract one first.
return start.subtract(BigInteger.ONE).nextProbablePrime();
}
/**
* Finds the largest 20-digit prime number by searching backward from (10^20 - 1).
*
* @param start Upper bound (10^20 - 1)
* @return The last 20-digit prime number
*/
public static BigInteger findLastPrime(BigInteger start) {
BigInteger candidate = start;
// Ensure we start searching from an odd number
if (candidate.testBit(0) == false) {
candidate = candidate.subtract(BigInteger.ONE);
}
// Search backward in steps of 2 until a prime is found.
// A certainty of 100 yields a error probability of <= (1/2)^100 (~1.27e-30).
while (!candidate.isProbablePrime(100)) {
candidate = candidate.subtract(BigInteger.TWO);
}
return candidate;
}
}
/*
run:
First 20-digit prime: 10000000000000000051
Last 20-digit prime: 99999999999999999989
*/