c++ - Highly Factorized Sieve of Eratosthenes -
just fun, i'm trying implement pseudocode this stackoverflow answer highly factorized sieve of eratosthenes in c++. can't figure out why code returns both prime , non-prime numbers. implementing these loops incorrectly? should using while loops instead? suspect i'm not incrementing loops properly. appreciated. i've spent several hours trying hunt down flaw.
gordonbgood's pseudocode inserted comments, , i've used same variable names.
#include <iostream> #include <vector> #include <cmath> const int limit = 1000000000; const std::vector<int> r {23,29,31,37,41,43,47,53, 59,61,67,71,73,79,83, //positions + 19 89,97,101,103,107,109,113,121,127, 131,137,139, 143,149,151,157,163,167,169,173,179,181,187,191,193, 197,199,209,211,221,223,227,229}; int main() { // array of length 11 times 13 times 17 times 19 = 46189 wheels initialized // doesn't contain multiples of large wheel primes // n n ← 210 × w + x w ∈ {0,...46189}, x in r: // // if (n mod cp) not equal 0 cp ∈ {11,13,17,19}: // no 2,3,5,7 // mstr(n) ← true else mstr(n) ← false // factors std::vector<bool> mstr(limit); int n; (int w=0; w <= 46189; ++w) { (auto x = begin(r); x != end(r); ++x) { n = 210*w + *x; if (n % 11 != 0 && n % 13 != 0 && n % 17 != 0 && n % 19 != 0) mstr[n]=true; else mstr[n]=false; } } // initialize sieve array of smaller wheels // enough wheels include representation limit // n n ← 210 × w + x, w ∈ {0,...(limit - 19) ÷ 210}, x in r: // sieve(n) ← mstr(n mod (210 × 46189)) // init pre-culled primes. std::vector<bool> sieve(limit+1000); (int w=0; w <= (limit-19)/210; ++w) { (auto x = begin(r); x != end(r); ++x) { n = 210*w + *x; sieve[n] = mstr[(n % (210*46189))]; } } // eliminate composites sieving, occurrences on // wheel using wheel factorization version of sieve of eratosthenes // n² ≤ limit when n ← 210 × k + x k ∈ {0..}, x in r // if sieve(n): // // n prime, cull multiples // s ← n² - n × (x - 23) // zero'th modulo cull start position // while c0 ≤ limit when c0 ← s + n × m m in r: // c0d ← (c0 - 23) ÷ 210, cm ← (c0 - 23) mod 210 + 23 //means cm in r // while c ≤ limit c ← 210 × (c0d + n × j) + cm // j ∈ {0,...}: // sieve(c) ← false // cull composites of prime int s, c, c0, c0d, cm, j; ( auto x = begin(r); x != end(r); ++x) { ( int k=0; (n=210*k + (*x)) <= sqrt(limit); ++k){ if (sieve[n]) { s = n*n - n*((*x)-23); ( auto m = begin(r); (c0=s+n*(*m)) <= limit && m != end(r); ++m) { c0d = (c0-23)/210; cm = (c0-23)%210 + 23; ( int j=0; (c=210*(c0d+n*j)+cm) <= limit; ++j) { sieve[c] = false; } } } } } // output 2, 3, 5, 7, 11, 13, 17, 19, // n ≤ limit when n ← 210 × k + x k ∈ {0..}, x in r: // if sieve(n): output n std::cout << "2\n3\n5\n7\n11\n13\n17\n19\n"; ( auto x = begin(r); x != end(r); ++x) { ( int k = 0; (n=210*k + (*x)) <= limit; ++k) { if (sieve[n]); std::cout << n << std::endl; } } std::cout << std::endl; return 0; }
Comments
Post a Comment