#include "nth_prime.h" #include #include #include #include namespace prime { using namespace std; number_t nth(size_t n, size_t sieve_size) { if (n < 1) throw domain_error("invalid prime number index"); vector primes = {2, 3, 5, 7, 11, 13}; if (n <= primes.size()) return primes[n - 1]; primes.reserve(n); if (auto_sieve_size == sieve_size) { sieve_size = min(size_t(32 * 1024), size_t(n * (log(n) + log(log(n))) + 0.5)); } vector sieve(sieve_size, false); sieve[0] = sieve[1] = true; size_t first_number = 0; while (true) { for (auto p : primes) { size_t reminder = first_number % p; size_t begin = reminder ? p - reminder : 0; for (size_t i = begin; i < sieve_size; i += p) { sieve[i] = true; } } for (size_t i = 0; i < sieve_size; ++i) { if (sieve[i]) continue; number_t p = first_number + i; primes.push_back(p); if (primes.size() == n) return p; for (size_t j = i; j < sieve_size; j += p) { sieve[j] = true; } } size_t next_first_number = first_number + sieve_size; if (next_first_number < first_number) throw runtime_error("failed to reach prime number"); first_number = next_first_number; memset(&sieve[0], false, sieve.size()*sizeof(sieve[0])); } } }