Add exercise: [11] Lucas–Lehmer primality test - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 611db6bdb6a5a08b628f571451a94a1147a0e16f | |
parent f2734fde832c3f45d0dc9350c561d4137a422788 | |
Author: Mattias Andrée <[email protected]> | |
Date: Mon, 25 Jul 2016 00:50:52 +0200 | |
Add exercise: [11] Lucas–Lehmer primality test | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M doc/exercises.tex | 85 +++++++++++++++++++++++++++++… | |
1 file changed, 85 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/doc/exercises.tex b/doc/exercises.tex | |
@@ -143,6 +143,43 @@ called a base.) | |
+\item {[\textit{11}]} \textbf{Lucas–Lehmer primality test} | |
+ | |
+The Lucas–Lehmer primality test can be used to determine | |
+whether a Mersenne numbers $M_n = 2^n - 1$ is a prime (a | |
+Mersenne prime). $M_n$ is a prime if and only if | |
+$s_{n - 1} \equiv 0 ~(\text{Mod}~M_n)$, where | |
+ | |
+\( \displaystyle{ | |
+ s_i = \left \{ \begin{array}{ll} | |
+ 4 & \text{if} ~ i = 0 \\ | |
+ s_{i - 1}^2 - 2 & \text{otherwise}. | |
+ \end{array} \right . | |
+}\) | |
+ | |
+\noindent | |
+The Lucas–Lehmer primality test requires that $n \ge 3$, | |
+however $M_2 = 2^2 - 1 = 3$ is a prime. Implement a version | |
+of the Lucas–Lehmer primality test that takes $n$ as the | |
+input. For some more fun, when you are done, you can | |
+implement a version that takes $M_n$ as the input. | |
+ | |
+For improved performance, instead of using \texttt{zmod}, | |
+you can use the recursive function | |
+% | |
+\( \displaystyle{ | |
+ k ~\mbox{Mod}~ 2^n - 1 = | |
+ \left ( | |
+ (k ~\mbox{Mod}~ 2^n) + \lfloor k \div 2^n \rfloor | |
+ \right ) ~\mbox{Mod}~ 2^n - 1, | |
+}\) | |
+% | |
+where $k ~\mbox{Mod}~ 2^n$ is efficiently calculated | |
+using \texttt{zand($k$, $2^n - 1$)}. (This optimisation | |
+is not part of the difficulty rating of this problem.) | |
+ | |
+ | |
+ | |
\end{enumerate} | |
@@ -348,4 +385,52 @@ enum zprimality ptest_fermat(z_t witness, z_t p, int t) | |
+\item \textbf{Lucas–Lehmer primality test} | |
+ | |
+\vspace{-1em} | |
+\begin{alltt} | |
+enum zprimality ptest_llt(z_t n) | |
+\{ | |
+ z_t s, M; | |
+ int c; | |
+ size_t p; | |
+ | |
+ if ((c = zcmpu(n, 2)) <= 0) | |
+ return c ? NONPRIME : PRIME; | |
+ | |
+ if (n->used > 1) \{ | |
+ \textcolor{c}{/* \textrm{An optimised implementation would not need th… | |
+ errno = ENOMEM; | |
+ return (enum zprimality)(-1); | |
+ \} | |
+ | |
+ zinit(s), zinit(M), zinit(2); | |
+ | |
+ p = (size_t)(n->chars[0]); | |
+ zsetu(s, 1), zsetu(M, 0); | |
+ zbset(M, M, p, 1), zsub(M, M, s); | |
+ zsetu(s, 4); | |
+ zsetu(two, 2); | |
+ | |
+ p -= 2; | |
+ while (p--) \{ | |
+ zsqr(s, s); | |
+ zsub(s, s, two); | |
+ zmod(s, s, M); | |
+ \} | |
+ c = zzero(s); | |
+ | |
+ zfree(two), zfree(M), zfree(s); | |
+ return c ? PRIME : NONPRIME; | |
+\} | |
+\end{alltt} | |
+ | |
+$M_n$ is composite if $n$ is composite, therefore, | |
+if you do not expect prime-only values on $n$, the | |
+performance can be improve by using some other | |
+primality test (or this same test if $n$ is a | |
+Mersenne number) to first check that $n$ is prime. | |
+ | |
+ | |
+ | |
\end{enumerate} |