r_with_128.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <gmp.h>
  2. #include <iostream>
  3. using namespace std;
  4. bool fermat_test(unsigned long long int num) {
  5. __uint128_t power = 2;
  6. __uint128_t result = 1;
  7. __uint128_t mod = num;
  8. unsigned long long int n = num-1;
  9. while (n)
  10. {
  11. if (n & 1)
  12. result = (result * power) % mod;
  13. power = (power * power) % mod;
  14. n >>= 1;
  15. }
  16. return (result == 1);
  17. }
  18. bool is_fermat_prime(unsigned long long int n) {
  19. return (fermat_test(n) == 1);
  20. }
  21. bool probprime(unsigned long long int k, mpz_t n) {
  22. mpz_set_ui(n, k);
  23. return mpz_probab_prime_p(n, 0);
  24. }
  25. bool is_chernick(int n, unsigned long long int m, mpz_t z) {
  26. if (6*m + 1 < 9223372036854775807LL) {
  27. if (!is_fermat_prime((6*m + 1))) {
  28. return false;
  29. }
  30. }
  31. if (12*m + 1 < 9223372036854775807LL) {
  32. if (!is_fermat_prime((12*m + 1))) {
  33. return false;
  34. }
  35. }
  36. for (unsigned long long int i = 1; i <= n - 2; i++) {
  37. if ((1 << i) * 9 * m + 1 < 9223372036854775807LL) {
  38. if (!is_fermat_prime( ((1 << i) * 9 * m + 1))) {
  39. return false;
  40. }
  41. }
  42. else {
  43. break;
  44. }
  45. }
  46. if (!probprime(6 * m + 1, z)) {
  47. return false;
  48. }
  49. if (!probprime(12 * m + 1, z)) {
  50. return false;
  51. }
  52. for (unsigned long long int i = 1; i <= n - 2; i++) {
  53. if (!probprime((1 << i) * 9 * m + 1, z)) {
  54. return false;
  55. }
  56. }
  57. return true;
  58. }
  59. int main() {
  60. mpz_t z;
  61. mpz_inits(z, NULL);
  62. // k = 24237176657 (for n = 12)
  63. // when done, check the range from k = 38637176656 to 40237176657
  64. // m = 31023586121600 (for n = 11)
  65. // m = 3208386195840 (for n = 10)
  66. //~ Tested up to k = 25000000000
  67. //~ Tested up to k = 26000000000
  68. //~ Tested up to k = 27000000000
  69. // ....
  70. //~ Tested up to k = 41000000000
  71. //~ Tested up to k = 41500000000
  72. //~ Tested up to k = 42000000000
  73. //~ Tested up to k = 42500000000
  74. //~ Tested up to k = 43000000000
  75. //~ Tested up to k = 46000000000
  76. //~ Tested up to k = 46500000000
  77. int n = 11;
  78. unsigned long long int multiplier = 5 * (1 << (n - 4));
  79. for (unsigned long long int k = 48474353315-1000000; k <= 48474353315; k++) {
  80. if (k % 500000000 == 0) {
  81. cout << "Tested up to k = " << (unsigned long long int)k << endl;
  82. }
  83. if (is_chernick(n, k * multiplier, z)) {
  84. cout << (unsigned long long int)(k * multiplier) << endl;
  85. break;
  86. }
  87. }
  88. return 0;
  89. }