Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // https://codereview.stackexchange.com/q/189083
- // https://pastebin.com/JMdTxbeJ
- /* old-ns-new old-s-new
- primes < 25 47 47 p < 2^31 2.0 1.8
- 50 63 63 2^32 4.2 3.8
- 100 78 78
- 200 110 140 1e9 0.9 0.8
- 400 187 219 2e9 1.8 1.7
- 800 344 405 4e9 3.9 3.5
- 1600 639 780
- 3200 1295 1591 scroll down for
- 6400 2590 2995 faster version */
- #include "stdafx.h"
- #include <vector>
- #include <iostream>
- #include <math.h>
- #include <ctime>
- #include <Windows.h>
- using namespace std;
- typedef unsigned __int16 u16; vector<u16> p0;
- typedef unsigned __int32 u32; vector<u32> x; vector<u32> p;
- void buildP0(u32 m) { // p's <= sqrt(m)
- m = (u32)sqrt(m); p0.resize(6537); // 13 <= p < 2^16: 6537 p's
- u32 a = 13, b = 2, d = 5, i = 0;
- for (double rt; a <= m; d = 5, a += b ^= 6) {
- for (rt = sqrt(a); d <= rt; d += 2)
- if (a % d == 0) break;
- if (d > rt) p0[i++] = a;
- } p0.resize(i);
- }
- void buildX(u32 m) { // mark odd composites
- if (m < 5000) {
- m += m & 1; m >>= 1;
- u32 a = 1, b = 2, c = 3, d = 1 + (m >> 5);
- x.resize(d); x[0] = 0x9b4b3491;
- for (; a < d; a += 3) x[a] = 0x24924924;
- for (; b < d; b += 3) x[b] = 0x49249249;
- for (; c < d; c += 3) x[c] = 0x92492492;
- for (a = 1; a < d; a += 5) x[a] |= 0x42108421;
- for (a = 2; a < d; a += 5) x[a] |= 0x10842108;
- for (a = 3; a < d; a += 5) x[a] |= 0x84210842;
- for (a = 4; a < d; a += 5) x[a] |= 0x21084210;
- for (a = 5; a < d; a += 5) x[a] |= 0x08421084;
- for (a = 7, b = 24, c = 12; b < m; a += 2, b += c += 4)
- if ((x[a >> 6] & 1 << (a >> 1)) == 0)
- for (d = b; d < m; d += a) x[d >> 5] |= 1 << d;
- x[m >> 5] |= ~0u << m;
- }
- else {
- buildP0(m); int i, j = p0.size();
- m -= m / ~0u; m += m & 1; m >>= 1;
- u32 r0, r1 = 0, a = 1, b = 1, c = 1, d = m >> 5;
- x.resize(d + 1); x[0] = 0x9b4b3491;
- for (;;) {
- if (a > d) break; x[a++] = 0x24924924;
- if (a > d) break; x[a++] = 0x49249249;
- if (a > d) break; x[a++] = 0x92492492;
- } for (;;) {
- if (b > d) break; x[b++] |= 0x42108421;
- if (b > d) break; x[b++] |= 0x10842108;
- if (b > d) break; x[b++] |= 0x84210842;
- if (b > d) break; x[b++] |= 0x21084210;
- if (b > d) break; x[b++] |= 0x08421084;
- } for (;;) {
- if (c > d) break; x[c++] |= 0x08102040;
- if (c > d) break; x[c++] |= 0x40810204;
- if (c > d) break; x[c++] |= 0x04081020;
- if (c > d) break; x[c++] |= 0x20408102;
- if (c > d) break; x[c++] |= 0x02040810;
- if (c > d) break; x[c++] |= 0x10204081;
- if (c > d) break; x[c++] |= 0x81020408;
- } while ((r0 = r1) < m) { // L1 64 KB / 2 = 0x40000
- if ((r1 += 0x40000) > m) r1 = m;
- for (i = 0, a = 11, b = 60; b < r1; a = p0[i++], b = a * a >> 1) {
- if (b < r0) { b += (r0 - b) / a * a; if (b < r0) b += a; }
- while (b < r1) { x[b >> 5] |= 1 << b; b += a; }
- if (i == j) break;
- }
- } x[m >> 5] |= ~0u << m;
- }
- }
- void countPrimes() {
- u32 c = 1; int i = x.size() - 1;
- while (i >= 0) c += __popcnt(~x[i--]);
- p.resize(c);
- }
- void primes(u32 m) { // primes <= m
- if (m < 2) return;
- buildX(m); countPrimes(); p[0] = 2;
- u32 u = ~0u, v = ~0u, xi; DWORD tz;
- for (int i = 0, n = 1, c = p.size(); n < c; v = u += 64)
- for (xi = ~x[i++]; xi; p[n++] = v += (tz + 1) << 1) {
- _BitScanForward(&tz, xi); xi >>= tz; xi >>= 1;
- }
- }
- void main()
- {
- primes(1000); x.resize(0); p.resize(0);
- for (u32 m = 25; m < 6401; m <<= 1) // for (u32 m = 0; m < 9; m++)
- {
- primes(m);
- if (m > 1)
- {
- u32 maxP = p[p.size() - 1];
- cout << "largest prime <= " << m << ": " << maxP << " ";
- }
- clock_t clock0 = clock();
- for (int i = 1000000; i; i--)
- {
- x.resize(0); p.resize(0); primes(m);
- }
- cout << clock() - clock0 << " ns: ";
- cout << p.size() << " primes" << endl << endl;
- }
- x.resize(0); p.resize(0); u32 m = (u32)4e9;
- clock_t clock0 = clock(); primes(m);
- cout << clock() - clock0 << " ms: ";
- cout << p.size() << " primes <= " << m;
- for (int j = p.size(), i = j - 5; i < j;) cout << endl << p[i++];
- getchar();
- }
- /* old-ns-new old-s-new
- primes < 25 47 62 p < 2^31 1.8 1.8
- 50 63 78 2^32 3.8 3.7
- 100 78 78
- 200 140 124 1e9 0.8 0.8
- 400 219 203 2e9 1.7 1.6
- 800 405 359 4e9 3.5 3.4
- 1600 780 687
- 3200 1591 1372
- 6400 2995 2684 */
- #include "stdafx.h"
- #include <vector>
- #include <iostream>
- #include <math.h>
- #include <ctime>
- #include <Windows.h>
- using namespace std;
- typedef unsigned __int16 u16; u16 *p1;
- typedef unsigned __int32 u32; u32 *x; vector<u32> p;
- int p1Size, xSize;
- void buildP1(u32 m) { // p's <= sqrt(m)
- m = (u32)sqrt(m); u16 *p0 = new u16[6537];
- u32 a = 13, b = 2, d = 5, i = 0;
- for (double rt; a <= m; d = 5, a += b ^= 6) {
- for (rt = sqrt(a); d <= rt; d += 2)
- if (a % d == 0) break;
- if (d > rt) p0[i++] = a;
- } p1 = new u16[p1Size = i]; memcpy(p1, p0, i << 1);
- }
- void buildX(u32 m) { // mark odd composites
- if (m < 80000) {
- m += m & 1; m >>= 1;
- u32 a = 1, b = 2, c = 3, d = 1 + (m >> 5);
- x = new u32[d]; x[0] = 0x9b4b3491;
- for (; a < d; a += 3) x[a] = 0x24924924;
- for (; b < d; b += 3) x[b] = 0x49249249;
- for (; c < d; c += 3) x[c] = 0x92492492;
- for (a = 1; a < d; a += 5) x[a] |= 0x42108421;
- for (a = 2; a < d; a += 5) x[a] |= 0x10842108;
- for (a = 3; a < d; a += 5) x[a] |= 0x84210842;
- for (a = 4; a < d; a += 5) x[a] |= 0x21084210;
- for (a = 5; a < d; a += 5) x[a] |= 0x08421084;
- for (a = 7, b = 24, c = 12; b < m; a += 2, b += c += 4)
- if ((x[a >> 6] & 1 << (a >> 1)) == 0)
- for (d = b; d < m; d += a) x[d >> 5] |= 1 << d;
- x[m >> 5] |= ~0u << m;
- }
- else {
- buildP1(m); int i, j = p1Size;
- m -= m / ~0u; m += m & 1; m >>= 1;
- u32 r0, r1 = 0, a = 1, b = 1, c = 1, d = xSize = m >> 5;
- x = new u32[d + 1]; x[0] = 0x9b4b3491;
- for (;;) {
- if (a > d) break; x[a++] = 0x24924924;
- if (a > d) break; x[a++] = 0x49249249;
- if (a > d) break; x[a++] = 0x92492492;
- } for (;;) {
- if (b > d) break; x[b++] |= 0x42108421;
- if (b > d) break; x[b++] |= 0x10842108;
- if (b > d) break; x[b++] |= 0x84210842;
- if (b > d) break; x[b++] |= 0x21084210;
- if (b > d) break; x[b++] |= 0x08421084;
- } for (;;) {
- if (c > d) break; x[c++] |= 0x08102040;
- if (c > d) break; x[c++] |= 0x40810204;
- if (c > d) break; x[c++] |= 0x04081020;
- if (c > d) break; x[c++] |= 0x20408102;
- if (c > d) break; x[c++] |= 0x02040810;
- if (c > d) break; x[c++] |= 0x10204081;
- if (c > d) break; x[c++] |= 0x81020408;
- } while ((r0 = r1) < m) {
- if ((r1 += 0x40000) > m) r1 = m;
- for (i = 0, a = 11, b = 60; b < r1; a = p1[i++], b = a * a >> 1) {
- if (b < r0) { b += (r0 - b) / a * a; if (b < r0) b += a; }
- while (b < r1) { x[b >> 5] |= 1 << b; b += a; }
- if (i == j) break;
- }
- } x[m >> 5] |= ~0u << m; delete[]p1;
- }
- }
- void countPrimes() {
- u32 c = 1; int i = xSize;
- while (i >= 0) c += __popcnt(~x[i--]);
- p.resize(c);
- }
- void primes(u32 m) { // primes <= m
- if (m < 2) return;
- buildX(m); countPrimes(); p[0] = 2;
- u32 u = ~0u, v = ~0u, xi; DWORD tz;
- for (int i = 0, n = 1, c = p.size(); n < c; v = u += 64)
- for (xi = ~x[i++]; xi; p[n++] = v += (tz + 1) << 1) {
- _BitScanForward(&tz, xi); xi >>= tz; xi >>= 1;
- } delete[]x;
- }
- void main()
- {
- clock_t clock0; primes(1000);
- for (u32 m = 25; m < 6401; m <<= 1)
- {
- primes(m);
- if (m > 1) cout << "maxP <= " << m << ": " << p[p.size() - 1] << " ";
- clock0 = clock();
- for (int i = 1000000; i; i--) primes(m);
- cout << clock() - clock0 << " ns: ";
- cout << p.size() << " primes" << endl << endl;
- }
- u32 m = (u32)1e9;
- clock0 = clock(); primes(m);
- cout << clock() - clock0 << " ms: ";
- cout << p.size() << " primes <= " << m;
- for (int j = p.size(), i = j - 5; i < j;) cout << endl << p[i++];
- getchar();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement