Guest User

Untitled

a guest
Aug 16th, 2015
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.23 KB | None | 0 0
  1. #define NOMINMAX // due to conflict with max()
  2. #include <windows.h> // warning: no C++ standard!
  3.  
  4. #include "MyBigUnsigned.h" // http://henkessoft.de/Sonstiges/MyBigUnsigned.rar
  5. // based on https://mattmccutchen.net/bigint/
  6.  
  7. #include <iostream>
  8. #include <cstdint>
  9. #include <vector>
  10. #include <cassert>
  11. #include <thread>
  12. #include <mutex>
  13.  
  14. using namespace std;
  15.  
  16. const uint32_t numberOfThreads = 11;
  17. const uint32_t DIVISOR_PRECHECK_MAX = 293;
  18. uint64_t const primeLimit = 100000000;
  19. uint64_t frequency;
  20.  
  21. mutex mutex0;
  22.  
  23. void textcolor(unsigned short color = 15)
  24. {
  25. SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), color);
  26. }
  27.  
  28. uint64_t convertBigToU64(BigUnsigned num)
  29. {
  30. BigUnsigned ZweiHochVierUndSechzig = stringToBigUnsigned("18446744073709551616");
  31. assert(num < ZweiHochVierUndSechzig);
  32. uint64_t jHi = num.getBlock(1);
  33. uint64_t jLo = num.getBlock(0);
  34. return (jHi << 32 | jLo);
  35. }
  36.  
  37. void convertU64ToBig(uint64_t num, BigUnsigned& b)
  38. {
  39. uint32_t numLo = (uint32_t)(num & 0xFFFFFFFF);
  40. uint32_t numHi = (uint32_t)((num >> 32) & 0xFFFFFFFF);
  41. b.setBlock(0, numLo);
  42. b.setBlock(1, numHi);
  43. }
  44.  
  45. BigUnsigned calculateMersenneNumber(BigUnsigned p)
  46. {
  47. BigUnsigned x = 2;
  48.  
  49. for (BigUnsigned i = 1; i < p; ++i)
  50. {
  51. x <<= 1;
  52. }
  53. return (x - 1);
  54. }
  55.  
  56. bool LucasLehmerTest(BigUnsigned m, BigUnsigned p)
  57. {
  58. BigUnsigned s = 4;
  59.  
  60. for (BigUnsigned i = 2; i < p; ++i)
  61. s = (s*s - 2) % m;
  62.  
  63. return (s == 0);
  64. }
  65.  
  66. // division test with first prime numbers
  67. BigUnsigned divisionPrecheck(vector<bool>& primes, BigUnsigned m)
  68. {
  69. for (BigUnsigned divisor = 7; divisor <= DIVISOR_PRECHECK_MAX; ++divisor)
  70. {
  71. if (primes[convertBigToU64(divisor)])
  72. {
  73. if (m % divisor == 0)
  74. {
  75. return divisor;
  76. }
  77. }
  78. }
  79.  
  80. return 0; // No divisor found
  81. }
  82.  
  83. void mersennePrimeCheck(vector<bool>& primes, uint64_t startCount, uint64_t lastCount, uint64_t startP, uint64_t limitP)
  84. {
  85. BigUnsigned bigStartP, bigLimitP;
  86. convertU64ToBig(startP, bigStartP);
  87. convertU64ToBig(limitP, bigLimitP);
  88.  
  89. for (BigUnsigned p = bigStartP; p < bigLimitP; ++p)
  90. {
  91. // primes lookup for p: in order for M(p) to be prime, p must itself be prime.
  92. if (!primes[convertBigToU64(p)])
  93. continue;
  94.  
  95. // if p is prime, then we calculate the mersenne number
  96. BigUnsigned m = calculateMersenneNumber(p);
  97.  
  98. // mersenne number with prime factors are no mersenne primes
  99. if (p > 19)
  100. {
  101. BigUnsigned divisor(0);
  102. divisor = divisionPrecheck(primes, m);
  103. if (divisor !=0)
  104. {
  105. mutex0.lock();
  106. textcolor(3);
  107. cout << ">>> divisionPrecheck finds " << divisor << " for p = " << p << " <<<" << endl;
  108. mutex0.unlock();
  109. continue;
  110. }
  111. }
  112.  
  113. if (LucasLehmerTest(m, p))
  114. {
  115. QueryPerformanceCounter((LARGE_INTEGER*)&lastCount);
  116. uint64_t delta = lastCount - startCount;
  117.  
  118. mutex0.lock();
  119. textcolor(15);
  120. cout << "p: " << p;
  121. textcolor(2);
  122. cout << "\ttime: " << 1000 * delta / frequency << " ms" << endl;
  123. mutex0.unlock();
  124. }
  125. }
  126.  
  127. mutex0.lock();
  128. textcolor(11);
  129. cout << "work is done for " << bigStartP << " to " << bigLimitP-1 << endl;
  130. mutex0.unlock();
  131. }
  132.  
  133. int main()
  134. {
  135. uint64_t startCount = 0, lastCount = 0, delta = 0;
  136. QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
  137. cout << "cpu frequency: " << frequency << " Hz" << endl;
  138. cout << "DIVISOR_PRECHECK_MAX: " << DIVISOR_PRECHECK_MAX << endl;
  139. cout << "number of threads: " << numberOfThreads << endl;
  140.  
  141. ////////////////////////// Generate primes lookup table /////////////////////////////////////////////////////////////
  142.  
  143. vector<bool> primes(primeLimit + 1); // calculated primes (low values)
  144.  
  145. primes[0] = primes[1] = false;
  146. for (uint64_t i = 2; i < primeLimit + 1; ++i) { primes[i] = true; }
  147.  
  148. // Erastothenes sieving loop
  149. uint64_t iMax = (uint64_t)sqrt((double)primeLimit) + 1;
  150. for (uint64_t i = 2; i < iMax; ++i)
  151. {
  152. if (primes[i])
  153. {
  154. for (uint64_t j = 2 * i; j < primeLimit + 1; j += i)
  155. {
  156. primes[j] = false;
  157. }
  158. }
  159. }
  160.  
  161. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  162.  
  163. cout << "Lucas Lehmer prime test for mersenne numbers" << endl; // https://de.wikipedia.org/wiki/Lucas-Lehmer-Test
  164.  
  165. QueryPerformanceCounter((LARGE_INTEGER*)&startCount);
  166.  
  167. vector<thread> t;
  168. uint64_t startP = 0;
  169. uint64_t limitP = 2400;
  170.  
  171. for (int x = 0; x < numberOfThreads; ++x)
  172. {
  173. t.emplace_back(mersennePrimeCheck, primes, startCount, lastCount, startP + x * 2400, limitP + x * 2400);
  174. }
  175.  
  176. for (int x = 0; x < numberOfThreads; ++x)
  177. {
  178. t[x].join(); // main has to wait for the results of the threads.
  179. }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment