In the search for Mersenne prime numbers it is advantageous to eliminate exponents by finding a small factor before starting a, potentially lengthy, <ahref="https://rosettacode.org/wiki/Lucas-Lehmer test"title="Lucas-Lehmer test"target="_blank">Lucas-Lehmer test</a>.
There are very efficient algorithms for determining if a number divides 2<sup>P</sup>-1 (or equivalently, if 2<sup>P</sup> mod (the number) = 1).
Some languages already have built-in implementations of this exponent-and-mod operation (called modPow or similar).
The following is how to implement this modPow yourself:
For example, let's compute 2<sup>23</sup> mod 47.
Convert the exponent 23 to binary, you get 10111. Starting with <tt>square</tt> = 1, repeatedly square it.
Remove the top bit of the exponent, and if it's 1 multiply <tt>square</tt> by the base of the exponentiation (2), then compute <tt>square</tt> modulo 47.
Use the result of the modulo from the last step as the initial value of <tt>square</tt> in the next step:
<pre>
Remove Optional
square top bit multiply by 2 mod 47
------------ ------- ------------- ------
1*1 = 1 1 0111 1*2 = 2 2
2*2 = 4 0 111 no 4
4*4 = 16 1 11 16*2 = 32 32
32*32 = 1024 1 1 1024*2 = 2048 27
27*27 = 729 1 729*2 = 1458 1
</pre>
Since 2<sup>23</sup> mod 47 = 1, 47 is a factor of 2<sup>P</sup>-1.
(To see this, subtract 1 from both sides: 2<sup>23</sup>-1 = 0 mod 47.)
Since we've shown that 47 is a factor, 2<sup>23</sup>-1 is not prime.
Further properties of Mersenne numbers allow us to refine the process even more.
Any factor q of 2<sup>P</sup>-1 must be of the form 2kP+1, k being a positive integer or zero. Furthermore, q must be 1 or 7 mod 8.
Finally any potential factor q must be <ahref="https://rosettacode.org/wiki/Primality by Trial Division"title="Primality by Trial Division"target="_blank">prime</a>.
As in other trial division algorithms, the algorithm stops when 2kP+1 > sqrt(N).These primality tests only work on Mersenne numbers where P is prime. For example, M<sub>4</sub>=15 yields no factors using these techniques, but factors into 3 and 5, neither of which fit 2kP+1.
testString: assert.equal(check_mersenne(23),"M23 = 2^23-1 is composite with factor 47",'<code>check_mersenne(23)</code> should return "M23 = 2^23-1 is composite with factor 47".');
testString: assert.equal(check_mersenne(929),"M929 = 2^929-1 is composite with factor 13007",'<code>check_mersenne(929)</code> should return "M929 = 2^929-1 is composite with factor 13007');