You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
1.9 KiB

25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
  1. // Check whether a mersenne number is prime,
  2. // using the Lucas-Lehmer test.
  3. // [Donald Ervin Knuth: The Art of Computer Programming, Vol. II:
  4. // Seminumerical Algorithms, second edition. Section 4.5.4, p. 391.]
  5. // We work with integers.
  6. #include <cln/integer.h>
  7. using namespace std;
  8. using namespace cln;
  9. // Checks whether 2^q-1 is prime, q an odd prime.
  10. bool mersenne_prime_p (int q)
  11. {
  12. cl_I m = ((cl_I)1 << q) - 1;
  13. int i;
  14. cl_I L_i;
  15. for (i = 0, L_i = 4; i < q-2; i++)
  16. L_i = mod(L_i*L_i - 2, m);
  17. return (L_i==0);
  18. }
  19. // Same thing, but optimized.
  20. bool mersenne_prime_p_opt (int q)
  21. {
  22. cl_I m = ((cl_I)1 << q) - 1;
  23. int i;
  24. cl_I L_i;
  25. for (i = 0, L_i = 4; i < q-2; i++) {
  26. L_i = square(L_i) - 2;
  27. L_i = ldb(L_i,cl_byte(q,q)) + ldb(L_i,cl_byte(q,0));
  28. if (L_i >= m)
  29. L_i = L_i - m;
  30. }
  31. return (L_i==0);
  32. }
  33. // Now we work with modular integers.
  34. #include <cln/modinteger.h>
  35. // Same thing, but using modular integers.
  36. bool mersenne_prime_p_modint (int q)
  37. {
  38. cl_I m = ((cl_I)1 << q) - 1;
  39. cl_modint_ring R = find_modint_ring(m); // Z/mZ
  40. int i;
  41. cl_MI L_i;
  42. for (i = 0, L_i = R->canonhom(4); i < q-2; i++)
  43. L_i = R->minus(R->square(L_i),R->canonhom(2));
  44. return R->equal(L_i,R->zero());
  45. }
  46. #include <cln/io.h> // we do I/O
  47. #include <stdlib.h> // declares exit()
  48. #include <cln/timing.h>
  49. int main (int argc, char* argv[])
  50. {
  51. if (!(argc == 2)) {
  52. cerr << "Usage: lucaslehmer exponent" << endl;
  53. exit(1);
  54. }
  55. int q = atoi(argv[1]);
  56. if (!(q >= 2 && ((q % 2)==1))) {
  57. cerr << "Usage: lucaslehmer q with q odd prime" << endl;
  58. exit(1);
  59. }
  60. bool isprime;
  61. { CL_TIMING; isprime = mersenne_prime_p(q); }
  62. { CL_TIMING; isprime = mersenne_prime_p_opt(q); }
  63. { CL_TIMING; isprime = mersenne_prime_p_modint(q); }
  64. cout << "2^" << q << "-1 is ";
  65. if (isprime)
  66. cout << "prime" << endl;
  67. else
  68. cout << "composite" << endl;
  69. }
  70. // Computing time on a i486, 33 MHz:
  71. // 1279: 2.02 s
  72. // 2281: 8.74 s
  73. // 44497: 14957 s