#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"); if (n == 1) return 2; vector primes = {3, 5, 7, 11, 13}; if (n - 2 < primes.size()) return primes[n - 2]; primes.reserve(n - 1); if (auto_sieve_size == sieve_size) { sieve_size = min(size_t(32 * 1024), size_t(0.5*(n * (log(n) + log(log(n)))) + 0.5)); } vector sieve(sieve_size, false); sieve[0] = true; size_t first_number = 1; while (true) { for (auto p : primes) { size_t reminder = (first_number % (2*p)); size_t begin = reminder > p ? 3*p - reminder : p - reminder; begin /= 2; 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 + 2*i; primes.push_back(p); if (primes.size() == n - 1) return p; for (size_t j = i; j < sieve_size; j += p) { sieve[j] = true; } } size_t next_first_number = first_number + 2*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])); } } }