Guest User

Untitled

a guest
Aug 16th, 2015
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.65 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. #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_K_MAX = 600;
  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 2*k*p+1
  66. BigUnsigned divisionPrecheck(BigUnsigned m, BigUnsigned p)
  67. {
  68.     for (BigUnsigned k = 1; k <= DIVISOR_PRECHECK_K_MAX; ++k)
  69.     {      
  70.         BigUnsigned Divisor = k * p;
  71.         Divisor <<= 1; // 2 * k * p
  72.         Divisor += 1; // 2 * k * p +1
  73.  
  74.         if (m % Divisor == 0)
  75.         {
  76.             return k;
  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 numbers with prime factors are no mersenne primes
  99.         if (p > 19)
  100.         {
  101.             BigUnsigned divisor = divisionPrecheck(m,p);
  102.             if (divisor !=0)
  103.             {
  104.                 /*
  105.                 mutex0.lock();
  106.                 textcolor(3);
  107.                 cout << ">>> divisionPrecheck (2*k*p+1) finds k = " << divisor << " for p = " << p << " <<<" << endl;
  108.                 mutex0.unlock();
  109.                 */
  110.                 continue;          
  111.             }
  112.         }
  113.        
  114.         if (LucasLehmerTest(m, p))
  115.         {
  116.             QueryPerformanceCounter((LARGE_INTEGER*)&lastCount);
  117.             uint64_t delta = lastCount - startCount;
  118.  
  119.             mutex0.lock();
  120.             textcolor(15);
  121.             cout << "p: " << p;
  122.             textcolor(2);
  123.             cout << "\ttime: " << 1000 * delta / frequency << " ms" << endl;
  124.             mutex0.unlock();
  125.         }
  126.     }
  127.    
  128.     mutex0.lock();
  129.     textcolor(11);
  130.     cout << "work is done for " << bigStartP << " to " << bigLimitP-1 << endl;
  131.     mutex0.unlock();
  132. }
  133.  
  134. int main()
  135. {
  136.     uint64_t startCount = 0, lastCount = 0, delta = 0;
  137.     QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
  138.     cout << "cpu frequency: " << frequency << " Hz" << endl;
  139.     cout << "DIVISOR_PRECHECK_K_MAX: " << DIVISOR_PRECHECK_K_MAX << endl;
  140.     cout << "number of threads: " << numberOfThreads << endl;
  141.    
  142.     ////////////////////////// Generate primes lookup table /////////////////////////////////////////////////////////////
  143.  
  144.     vector<bool> primes(primeLimit + 1); // calculated primes (low values)
  145.    
  146.     primes[0] = primes[1] = false;
  147.     for (uint64_t i = 2; i < primeLimit + 1; ++i) { primes[i] = true; }
  148.  
  149.     // Erastothenes sieving loop
  150.     uint64_t iMax = (uint64_t)sqrt((double)primeLimit) + 1;
  151.     for (uint64_t i = 2; i < iMax; ++i)
  152.     {
  153.         if (primes[i])
  154.         {
  155.             for (uint64_t j = 2 * i; j < primeLimit + 1; j += i)
  156.             {
  157.                 primes[j] = false;
  158.             }
  159.         }
  160.     }
  161.  
  162.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163.  
  164.     cout << "Lucas Lehmer prime test for mersenne numbers" << endl; // https://de.wikipedia.org/wiki/Lucas-Lehmer-Test
  165.  
  166.     QueryPerformanceCounter((LARGE_INTEGER*)&startCount);
  167.  
  168.     vector<thread> t;
  169.     uint64_t startP = 0;
  170.     uint64_t limitP = 2400;
  171.  
  172.     for (int x = 0; x < numberOfThreads; ++x)
  173.     {
  174.         t.emplace_back(mersennePrimeCheck, primes, startCount, lastCount, startP + x * 2400, limitP + x * 2400);
  175.     }
  176.  
  177.     for (int x = 0; x < numberOfThreads; ++x)
  178.     {
  179.         t[x].join(); // main has to wait for the results of the threads.
  180.     }
  181. }
Advertisement
Add Comment
Please, Sign In to add comment