Primes and the idea of a sieve
A prime is a number greater than 1 whose only divisors are 1 and itself: 2, 3, 5, 7, 11 ... Every other number greater than 1 is composite (it has a smaller divisor).
You can test one number n by trying to divide it by 2, 3, 4 ... up to √n. But if you want all primes up to n, there is a faster idea, thought of by the Greek scholar Eratosthenes more than 2000 years ago: do not test numbers, remove the ones that cannot be prime.
The algorithm step by step
- Write all numbers from 2 to n. Mark all of them "maybe prime".
- Take the smallest number p that is still marked. It is prime.
- Cross out its multiples p², p² + p, p² + 2p, ... up to n.
- Go back to step 2. Stop when p × p is bigger than n.
- Every number still not crossed out is prime.
Why start at p²? A smaller multiple like 5 × 3 was already crossed out when we handled 3. Every composite number has a prime factor that is at most its square root, so primes up to √n are enough.
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
p = 2
while p * p <= n:
if is_prime[p]:
for m in range(p * p, n + 1, p):
is_prime[m] = False
p += 1Speed: about n log log n steps, which is almost linear. For n = 10 million it finishes in a blink. Cost: memory for n flags.
Why we need long arithmetic
A normal integer variable can hold only a limited number. A 64-bit signed integer stops at about 9.2 × 10¹⁸, which has 19 digits. But 21! has 20 digits, and 100! has 158 digits. To work with such numbers, we use long arithmetic: keep the number as a list of digits (often stored with the smallest digit first) and do the school methods on this list.
The list can be as long as the memory allows. (Many languages, such as Python, have this built in; knowing how it works is the point.)
Adding, subtracting and multiplying long numbers
Addition. Go from the right. In every column compute s = a + b + carry. Write s mod 10 (the last digit of s). The new carry is s ÷ 10 (whole part). At the end, if the carry is not 0, write it as a new first digit. Cost: one step per digit, O(n).
Subtraction (bigger − smaller) works the same way but with a borrow instead of a carry: if a digit is too small, borrow 10 from the next column.
Long × small number. For each digit, compute d × k + carry; write the last digit and carry the rest. This is how you build factorials like 50!, multiplying a long number by 2, then 3, then 4 ...
Long × long is done like school multiplication: every digit of one number meets every digit of the other, about n × m steps.
Try it: add by columns, then sieve by hand
1) Write the numbers 2 to 50 in a 7 × 7 grid on paper. Use a red pencil and do exactly what the 3D does. Count how many numbers are left. (You should get 15.) 2) In the 3D, move the column slider and check each column of 874965 + 365879 with a pencil before looking at the answer.
Key formulas and definitions
- Sieve: cross out p², p² + p, p² + 2p, … up to n; stop when p² > n
- Time of the sieve ≈ n log log n
- Long addition, each column: s = a + b + carry; digit = s mod 10; carry = ⌊s / 10⌋
- Long × short: s = d × k + carry; digit = s mod 10; carry = ⌊s / 10⌋
- Number of digits of N ≈ ⌊log₁₀ N⌋ + 1
Worked examples
1. Use the sieve to find all primes up to 30. Which primes do you cross out multiples of?
Check p = 2, 3, 5 (since 5 × 5 = 25 ≤ 30, but 7 × 7 = 49 > 30). Cross multiples of 2, 3 and 5. What remains: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29. That is 10 primes.
2. When processing p = 5 for n = 50, from which number do we start crossing out? List the numbers crossed.
We start from 5² = 25. We cross 25, 30, 35, 40, 45, 50. (10, 15 and 20 were already crossed by 2 and 3.)
3. For n = 100, which primes p must we process, and how many primes remain?
We need all primes p with p × p ≤ 100, so p ≤ 10: they are 2, 3, 5 and 7 (4 rounds). Then 25 primes remain below 100.
4. Add 478 + 595 using columns.
Units: 8 + 5 = 13, write 3, carry 1. Tens: 7 + 9 + 1 = 17, write 7, carry 1. Hundreds: 4 + 5 + 1 = 10, write 0, carry 1. The carry 1 becomes the first digit: 1073.
5. Add 874965 + 365879 by columns (from the right).
5 + 9 = 14 → 4, carry 1. 6 + 7 + 1 = 14 → 4, carry 1. 9 + 8 + 1 = 18 → 8, carry 1. 4 + 5 + 1 = 10 → 0, carry 1. 7 + 6 + 1 = 14 → 4, carry 1. 8 + 3 + 1 = 12 → 2, carry 1. Last carry 1 goes in front: 1240844.
6. Multiply the long number 468 by 7 digit by digit.
From the right: 8 × 7 = 56 → write 6, carry 5. 6 × 7 + 5 = 47 → write 7, carry 4. 4 × 7 + 4 = 32 → write 2, carry 3. The carry 3 goes in front: 3276.
7. How many digits does 2⁶⁴ have?
2⁶⁴ = 18446744073709551616. Check with logs: 64 × log₁₀ 2 = 64 × 0.30103 = 19.27, so ⌊19.27⌋ + 1 = 20 digits.
Common mistakes
- Starting to cross out at 2p instead of p². It still works but wastes steps.
- Crossing out the prime itself. We cross only its multiples, not p.
- Continuing the sieve past √n. It is not needed, and it wastes time.
- Forgetting the last carry in long addition, so 99 + 1 becomes 00 instead of 100.