/// @param start Sieve primes >= start. /// @param stop Sieve primes <= stop. /// @param sieveSize A sieve size in kilobytes. /// @pre start >= 7 /// @pre stop <= 2^64 - 2^32 * 10 /// @pre sieveSize >= 1 && <= 2048 /// SieveOfEratosthenes::SieveOfEratosthenes(uint64_t start, uint64_t stop, uint_t sieveSize) : start_(start), stop_(stop), sieve_(NULL), preSieve_(NULL), eratSmall_(NULL), eratMedium_(NULL), eratBig_(NULL) { if (start_ < 7) throw primesieve_error("SieveOfEratosthenes: start must be >= 7"); if (start_ > stop_) throw primesieve_error("SieveOfEratosthenes: start must be <= stop"); // choose the fastest pre-sieve limit limitPreSieve_ = config::PRESIEVE; if ((stop_ - start_) < config::PRESIEVE_THRESHOLD) limitPreSieve_ = 13; sqrtStop_ = static_cast<uint_t>(isqrt(stop_)); // sieveSize_ must be a power of 2 sieveSize_ = getInBetween(1u, floorPowerOf2(sieveSize), 2048u); sieveSize_ *= 1024; // convert to bytes segmentLow_ = start_ - getByteRemainder(start_); segmentHigh_ = segmentLow_ + sieveSize_ * NUMBERS_PER_BYTE + 1; // allocate the sieve of Eratosthenes array sieve_ = new byte_t[sieveSize_]; init(); }
/// @param stop Upper bound for sieving. /// @param sieveSize Sieve size in bytes. /// @param limit Sieving primes in EratMedium must be <= limit. /// EratMedium::EratMedium(uint64_t stop, uint_t sieveSize, uint_t limit) : Modulo210Wheel_t(stop, sieveSize), limit_(limit) { // ensure multipleIndex < 2^23 in crossOff() if (sieveSize > (1u << 21)) throw primesieve_error("EratMedium: sieveSize must be <= 2^21, 2048 kilobytes"); if (limit > sieveSize * 9) throw primesieve_error("EratMedium: limit must be <= sieveSize * 9"); buckets_.push_back(Bucket()); }
void pushBack_N_Primes(uint64_t n, uint64_t start) { n_ = n; PrimeSieve ps; std::size_t newSize = primes_.size() + static_cast<std::size_t>(n_); primes_.reserve(newSize); try { while (n_ > 0) { // choose stop > nth prime uint64_t logx = 50; uint64_t dist = n_ * logx + 10000; uint64_t stop = start + dist; // fix integer overflow if (stop < start) stop = get_max_stop(); ps.callbackPrimes(start, stop, this); start = stop + 1; if (stop >= get_max_stop()) throw primesieve_error("cannot generate primes > 2^64"); } } catch (cancel_callback&) { } }
/// Set a stop number (upper bound) for sieving. /// @pre stop <= 2^64 - 2^32 * 10 /// void PrimeSieve::setStop(uint64_t stop) { uint64_t maxStop = PrimeFinder::getMaxStop(); if (stop > maxStop) throw primesieve_error("stop must be <= " + PrimeFinder::getMaxStopString()); stop_ = stop; }
/// @param stop Upper bound for sieving. /// @param sieveSize Sieve size in bytes. /// @param limit Sieving primes in EratSmall must be <= limit. /// EratSmall::EratSmall(uint64_t stop, uint_t sieveSize, uint_t limit) : Modulo30Wheel_t(stop, sieveSize), limit_(limit) { if (limit > sieveSize * 3) throw primesieve_error("EratSmall: limit must be <= sieveSize * 3"); buckets_.push_back(Bucket()); }
/// PreSieve multiples of small primes <= limit. /// @pre limit >= 11 && <= 23 /// PreSieve::PreSieve(int limit) : limit_(limit), preSieved_(NULL) { // limit_ <= 23 prevents 32-bit overflows if (limit_ < 11 || limit_ > 23) throw primesieve_error("PreSieve: limit must be >= 11 && <= 23"); init(); }
/// Massively parallel (unsynchronized) prime generation method for /// use with ParallelPrimeSieve. /// void PrimeSieve::callbackPrimes_c(uint64_t start, uint64_t stop, void (*callback)(uint64_t, int)) { if (!callback) throw primesieve_error("callback is NULL"); callback_tn_ = callback; flags_ = CALLBACK_PRIMES_C_TN; sieve(start, stop); }
/// Massively parallel (unsynchronized) prime generation method for /// use with ParallelPrimeSieve. /// void PrimeSieve::callbackPrimes(uint64_t start, uint64_t stop, Callback<uint64_t, int>* cb) { if (!cb) throw primesieve_error("Callback pointer is NULL"); cb_tn_ = cb; flags_ = CALLBACK_PRIMES_OBJ_TN; sieve(start, stop); }
/// @param stop Upper bound for sieving. /// @param sieveSize Sieve size in bytes. /// @param limit Sieving primes in EratBig must be <= limit, /// usually limit = sqrt(stop). /// EratBig::EratBig(uint64_t stop, uint_t sieveSize, uint_t limit) : Modulo210Wheel_t(stop, sieveSize), limit_(limit), log2SieveSize_(ilog2(sieveSize)), moduloSieveSize_(sieveSize - 1), stock_(NULL) { // '>> log2SieveSize' requires a power of 2 sieveSize if (!isPowerOf2(sieveSize)) throw primesieve_error("EratBig: sieveSize must be a power of 2"); init(sieveSize); }
void iterator::skipto(uint64_t start, uint64_t stop_hint) { if (start > get_max_stop()) throw primesieve_error("start must be <= " + PrimeFinder::getMaxStopString()); start_ = start; stop_ = start; stop_hint_ = stop_hint; i_ = 0; last_idx_ = 0; tiny_cache_size_ = 1 << 11; primes_.clear(); }
void iterator::generate_previous_primes() { primes_.clear(); while (primes_.empty()) { stop_ = subtract_underflow_safe(start_, 1); start_ = subtract_underflow_safe(stop_, get_interval_size(stop_)); if (start_ <= stop_hint_ && stop_ >= stop_hint_) start_ = subtract_underflow_safe(stop_hint_, max_prime_gap(stop_hint_)); primesieve::generate_primes(start_, stop_, &primes_); if (primes_.empty() && start_ < 2) throw primesieve_error("previous_prime(): smallest prime is 2"); } last_idx_ = primes_.size() - 1; i_ = last_idx_; }
void iterator::generate_next_primes() { primes_.clear(); while (primes_.empty()) { start_ = add_overflow_safe(stop_, 1); stop_ = add_overflow_safe(start_, get_interval_size(start_)); if (start_ <= stop_hint_ && stop_ >= stop_hint_) stop_ = add_overflow_safe(stop_hint_, max_prime_gap(stop_hint_)); primesieve::generate_primes(start_, stop_, &primes_); if (primes_.empty() && stop_ >= get_max_stop()) throw primesieve_error("next_prime() > " + PrimeFinder::getMaxStopString()); } last_idx_ = primes_.size() - 1; i_ = 0; }