1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/*
* Teste Laufzeit verschiedener Tests auf prim.
* Dazu werden jeweis eine messbare Anzahl von Zahlen
* verschiedener Grösse getestet:
* a) 1..100'000,
* b) 8'000'000..8'100'000,
* c) 1'000 vor ~0 bis ~0.
*
* 0. Version: 190519, MF
*
*/
#include <iostream> /* cout, cin, endl */
#include <ctime> /* clock */
#include <cmath> /* sqrt */
#include <cstdint> /* __uint128_t */
#include <bitset> /* for bool array of prime Y/N */
using namespace std;
#define tytok unsigned long long
/* from https://de.wikipedia.org/wiki/Miller-Rabin-Test#Implementierung */
#include <cstdint>
// using std::uint32_t;
// bool mrt (const uint32_t n, const uint32_t a) { // n ungerade, 1 < a < n-1
bool mrt (const tytok n, const tytok a) { // n ungerade, 1 < a < n-1
if( n < 2 ) return false; // MF
if( n == 2 ) return true; // MF
if( n == 3 ) return true; // MF
const tytok m = n - 1;
tytok d = m >> 1, e = 1;
while (!(d & 1)) d >>= 1, ++e;
__uint128_t p = a, q = a;
// unsigned long long p = a, q = a;
while (d >>= 1) { // exponentiere modular: p = a^d mod n
q *= q, q %= n; // quadriere modular: q = q^2 mod n
if (d & 1) p *= q, p %= n; // multipliziere modular: p = (p * q) mod n
}
if (p == 1 || p == m) return true; // n ist wahrscheinlich prim
while (--e) {
p *= p, p %= n;
if (p == m) return true;
if (p <= 1) break;
}
return false; // n ist nicht prim
}
/* function to check if n is a prime number uses simple trial division */
bool is_prime( tytok n )
{
if( n < 2 ) return false ;
if( n == 2 ) return true ; // 2 is a prime number
if( n%2 == 0 ) return false ; // even numbers greater than two are not prime
// trial division by odd numbers up to the square root of n
for( tytok div = 3 ; (div*div) <= n ; div += 2 ) if( n%div == 0 ) return false ;
return true ; // not evenly divisible by any of the candidates
}
/* source: https://www.codeproject.com/articles/465041/primality-test */
bool IsPrimeWithWheel(tytok number)
{
if ( number < 2 ) return false;
if ( number < 4 ) return true;
if ( number == 5 ) return true;
if (!(number % 2)) return false;
if (!(number % 3)) return false;
if (!(number % 5)) return false;
if ( number < 7*7) return true;
int wheel[] = {7, 11, 13, 17, 19, 23, 29, 31};
tytok rt = sqrt(number);
for(tytok r = 0; r < rt; r += 30)
for(int i = 0; i < 8; ++i)
if (!(number % (r + wheel[i])))
return false;
return true;
}
int main()
{
tytok lo(1), max(~0), mid(4000000000), delta1(1000000), delta2(1000);
tytok n, cnt(0);
clock_t t0 = clock(); /* time(R) */
for (n = lo; n <= lo+delta1; ++n)
if (mrt(n, 2)
&& mrt(n, 3)) cnt++;
double te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "MRT counts " << cnt << " primes from " << lo << " to " << lo + delta1 << " within " << te << " seconds.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = lo; n <= lo+delta1; ++n)
if (is_prime(n)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "SPC counts " << cnt << " primes from " << lo << " to " << lo + delta1 << " within " << te << " seconds.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = lo; n <= lo+delta1; ++n)
if (IsPrimeWithWheel(n)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "PWW counts " << cnt << " primes from " << lo << " to " << lo + delta1 << " within " << te << " seconds.\n";
for (n = lo; n <= lo+delta1; ++n)
if ((IsPrimeWithWheel(n)) != (mrt(n, 2) && mrt(n, 3)))
cout << "\nDiff: " << n << ", mrt(n, 2) .., 3): " << mrt(n, 2) << mrt(n, 3) << "\n\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = mid; n <= mid+delta1; ++n)
// if (mrt(n, 31) && mrt(n, 73))
if (mrt(n, 2)
&& mrt(n, 7)
&& mrt(n, 61)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "MRT counts " << cnt << " primes from " << mid << " to " << mid + delta1 << " within " << te << " seconds.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = mid; n <= mid+delta1; ++n)
if (is_prime(n)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "SPC counts " << cnt << " primes from " << mid << " to " << mid + delta1 << " within " << te << " seconds.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = mid; n <= mid+delta1; ++n)
if (IsPrimeWithWheel(n)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "PWW counts " << cnt << " primes from " << mid << " to " << mid + delta1 << " within " << te << " seconds.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = max - delta2; n < max; ++n)
if (mrt(n, 2) &&
mrt(n, 3) &&
mrt(n, 5) &&
mrt(n, 7) &&
mrt(n, 11) &&
mrt(n, 13) &&
mrt(n, 17) &&
mrt(n, 19) &&
mrt(n, 23)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "MRT counts " << cnt << " primes from " << max - delta2 << " to " << max << " within " << te << " seconds.\n";
/*
/* cnt = 0; t0 = clock(); /* time(R) */
/* for (n = max-delta2; n < max; ++n)
/* if (is_prime(n)) cnt++;
/* te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
/* cout << "SPC counts " << cnt << " primes from " << max - delta2 << " to " << max << " within " << te << " seconds.\n";
*/
cout << "SPC skipped.\n";
cnt = 0; t0 = clock(); /* time(R) */
for (n = max-delta2; n < max; ++n)
if (IsPrimeWithWheel(n)) cnt++;
te = (double)( clock() - t0 ) / CLOCKS_PER_SEC; /* time(E) */
cout << "PWW counts " << cnt << " primes from " << max - delta2 << " to " << max << " within " << te << " seconds.\n";
/*
for (n = max-delta2; n < max; ++n)
if ((is_prime(n)) != (mrt(n, 2) && mrt(n, 7) && mrt(n, 61)))
cout << "\nDiff: " << n << " SPC mrt(n, 2) ..7 ..61: " << is_prime(n) << ' ' << mrt(n, 2) << mrt(n, 7) << mrt(n, 61) << "\n\n";
*/
}
|