Advertisement
Guest User

Untitled

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