Lucas-Lehmer test: Difference between revisions
Content added Content deleted
(+Oz) |
No edit summary |
||
Line 150: | Line 150: | ||
int main() |
int main() |
||
{ |
{ |
||
mpz_class maxcount(45); |
|||
mpz_class found(0); |
|||
mpz_class check(0); |
|||
for( mpz_nextprime(check.get_mpz_t(), check.get_mpz_t()); |
|||
found < maxcount; |
|||
mpz_nextprime(check.get_mpz_t(), check.get_mpz_t())) |
|||
{ |
|||
{ |
|||
//std::cout << "P" << check << " " << std::flush; |
|||
if( is_mersenne_prime(check) ) |
|||
{ |
|||
{ |
|||
++found; |
|||
std::cout << "M" << check << " " << std::flush; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
} |
||
bool is_mersenne_prime(mpz_class p) |
bool is_mersenne_prime(mpz_class p) |
||
{ |
{ |
||
if( 2 == p ) |
|||
return true; |
|||
else |
|||
{ |
|||
{ |
|||
mpz_class div = pow2(p) - mpz_class(1); |
|||
mpz_class s(4); |
|||
mpz_class s(4); |
|||
for( mpz_class i(3); |
|||
i <= p; |
|||
++i ) |
|||
++i ) |
|||
{ |
|||
{ |
|||
s = (s * s - mpz_class(2)) % div ; |
|||
} |
|||
} |
|||
return ( s == mpz_class(0) ); |
|||
} |
|||
} |
|||
} |
} |
||
mpz_class pow2(mpz_class exp) |
mpz_class pow2(mpz_class exp) |
||
{ |
{ |
||
// Unfortunately, GMP doesn't have a left-shift method. |
|||
// It also doesn't have a pow() equivalent that takes arbitrary-precision exponents. |
|||
// So we have to do it the hard (and presumably slow) way. |
|||
mpz_class ret(2); |
|||
mpz_class ret(2); |
|||
for(mpz_class i(1); i < exp; ++i) |
|||
ret *= mpz_class(2); |
|||
ret *= mpz_class(2); |
|||
//std::cout << "pow2( " << exp << " ) = " << ret << std::endl; |
|||
return ret; |
|||
} |
} |
||
</pre> |
</pre> |
||
Line 345: | Line 345: | ||
{Application.exit 0} |
{Application.exit 0} |
||
end</ocaml> |
end</ocaml> |
||
=={{header|Pop11}}== |
|||
Checking large numbers takes a lot of time so we limit p to |
|||
be smaller than 1000. |
|||
<pre> |
|||
define Lucas_Lehmer_Test(p); |
|||
lvars mp = 2**p - 1, sn = 4, i; |
|||
for i from 2 to p - 1 do |
|||
(sn*sn - 2) rem mp -> sn; |
|||
endfor; |
|||
sn = 0; |
|||
enddefine; |
|||
lvars p = 3; |
|||
printf('M2', '%p\n'); |
|||
while p < 1000 do |
|||
if Lucas_Lehmer_Test(p) then |
|||
printf('M', '%p'); |
|||
printf(p, '%p\n'); |
|||
endif; |
|||
p + 2 -> p; |
|||
endwhile; |
|||
</pre> |
|||
The output (obtained in few seconds) is: |
|||
<pre> |
|||
M2 |
|||
M3 |
|||
M5 |
|||
M7 |
|||
M13 |
|||
M17 |
|||
M19 |
|||
M31 |
|||
M61 |
|||
M89 |
|||
M107 |
|||
M127 |
|||
M521 |
|||
M607 |
|||
<pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
from sys import stdout |
from sys import stdout |