The natural numbers $0, 1, 2, 3, \ldots$
Given natural numbers $n$, $d$:
$d$ is a proper divisor of $n$ if it is a divisor and $d \neq 1, n$
(n % d == 0)
returns true
if and only if d
divides n
Proper divisors of 12? 13?
A natural number $p > 1$ is prime if it has no proper divisors.
Examples:
$2, 3, 5, 7, 11, 17, 19$ are prime
$4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20$ are composite
The Task. Generate an array int[] primes
that contains every prime number that can be stored as an int
in Java in increasing order.
Integer.MAX_VALUE = 2_147_483_647
Method 1: Trial Division
n
to see if n
is divisble by them:public boolean isPrime(int n) {
if (n <= 1) return false;
for (int d = 2; d < n; ++d) {
if (n % d == 0)
return false;
}
return true;
}
Is 91 prime?
Can we improve trial division?
n-1
?Claim 1. If $n$ is composite, then it has a divisor $d$ with $d \leq \sqrt{n}$
Why?
Conclusion. Only need to check divisors up to $\sqrt{n}$
public boolean isPrime(int n) {
if (n <= 1) return false;
for (int d = 2; d * d <= n; ++d) {
if (n % d == 0)
return false;
}
return true;
}
Claim 2. If $n$ is composite, then it has a prime divisor at most $\sqrt{n}$.
So we only need to check primes up to $\sqrt{n}$
Example:
Suppose we want to generate all primes up to $N$…
How should we do this?
2
through N
02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28
29 30 31 32 33 34 35 36 37
In SoE, once we find primes up to Math.sqrt(N)
, we can stop!
Why?
isPrime
of size N
isPrime[i] == true
if i
is primeisPrime[i]
to true
for all i >= 2
i
up to Math.sqrt(N)
:
isPrime[i]
:
isPrime[j] = false
for all j
that are multiples of i
When done: isPrime[i]
is true precisely for prime i
boolean[] isPrime = new boolean[N];
for (int i = 2; i < N; ++i) {
isPrime[i] = true;
}
for (int i = 2; i < N; ++i) {
if (isPrime[i]) {
for (int j = 2 * i; j < N; j += i) {
isPrime[j] = false;
}
}
}
Let’s compute the primes up to $225 = 15^2$
To start, here are the primes up to 15:
1–44:
45–89:
90–134:
90–134:
135–179:
180–225:
Storing boolean isPrime
of size Integer.MAX_VALUE
is already on the order of 1GB of memory
How can we partition the problem to exploit parallelism?
How to synchronize between different sub-tasks?