URI: 
       Add exercises: - libzahl - big integer library
  HTML git clone git://git.suckless.org/libzahl
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 32f59d5fbed9dbfa913221ef37d8df9364b9963a
   DIR parent 2864613b162ed4c7a28a79c8c4dcd24893cc2128
  HTML Author: Mattias Andrée <maandree@kth.se>
       Date:   Thu, 28 Jul 2016 20:12:19 +0200
       
       Add exercises:
       
       [▶05] zlshu and zrshu
       [▶M15] Modular left-shift
       [▶08] Modular left-shift, extended
       [13] The totient
       
       Diffstat:
         M doc/exercises.tex                   |     134 +++++++++++++++++++++++++++++++
       
       1 file changed, 134 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/doc/exercises.tex b/doc/exercises.tex
       @@ -207,6 +207,67 @@ $\varphi$ is the golden ratio.
        
        
        
       +\item {[\textit{$\RHD$05}]} \textbf{zlshu and zrshu}
       +
       +Why does libzahl have
       +
       +\vspace{-1em}
       +\begin{alltt}
       +   void zlsh(z_t, z_t, size_t);
       +   void zrsh(z_t, z_t, size_t);
       +\end{alltt}
       +\vspace{-1em}
       +
       +\noindent
       +rather than
       +
       +\vspace{-1em}
       +\begin{alltt}
       +   void zlsh(z_t, z_t, z_t);
       +   void zrsh(z_t, z_t, z_t);
       +   void zlshu(z_t, z_t, size_t);
       +   void zrshu(z_t, z_t, size_t);
       +\end{alltt}
       +\vspace{-1em}
       +
       +
       +
       +\item {[$\RHD$M15]} \textbf{Modular left-shift}
       +
       +Implement a function that calculates
       +$2^a \text{ mod } b$, using \texttt{zmod} and
       +only cheap functions. You can assume $a \ge 0$,
       + $b \ge 1$. You can also assume that all
       +parameters are unique pointers.
       +
       +
       +
       +\item {[$\RHD$08]} \textbf{Modular left-shift, extended}
       +
       +{\small\textit{You should already have solved
       +``Modular left-shift'' before you solve this
       +problem.}}
       +
       +Extend the function you wrote in ``Modular left-shift''
       +to accept negative $b$ and non-unique pointers.
       +
       +
       +
       +\item {[13]} \textbf{The totient}
       +
       +The totient of $n$ is the number of integer $a$,
       +$0 < a < n$ that are relatively prime to $n$.
       +Implement Euler's totient function $\varphi(n)$
       +which calculates the totient of $n$. Its
       +formula is
       +
       +\( \displaystyle{
       +    \varphi(n) = n \prod_{p \in \textbf{P} : p | n}
       +    \left ( 1 - \frac{1}{p} \right ).
       +}\)
       +
       +
       +
        \end{enumerate}
        
        
       @@ -228,6 +289,7 @@ void monus(z_t r, z_t a, z_t b)
                zsetu(r, 0);
        \}
        \end{alltt}
       +\vspace{-1em}
        
        
        \item \textbf{Modular powers of 2}
       @@ -372,6 +434,7 @@ ptest_fast(z_t p)
            return c ? NONPRIME : PROBABLY_PRIME;
        \}
        \end{alltt}
       +\vspace{-1em}
        
        
        
       @@ -420,6 +483,7 @@ ptest_fermat(z_t witness, z_t p, int t)
            return rc;
        \}
        \end{alltt}
       +\vspace{-1em}
        
        
        
       @@ -539,6 +603,76 @@ golden_pow(z_t r, z_t n)
                lucas(r, n);
        \}
        \end{alltt}
       +\vspace{-1em}
       +
       +
       +
       +\item \textbf{zlshu and zrshu}
       +
       +You are in big trouble, memorywise, of you
       +need to evaluate $2^{2^{64}}$.
       +
       +
       +
       +\item \textbf{Modular left-shift}
       +
       +\vspace{-1em}
       +\begin{alltt}
       +void modlsh(z_t r, z_t a, z_t b)
       +\{
       +    z_t t, at;
       +    size_t s = zbits(b);
       +
       +    zinit(t), zinit(at);
       +    zset(at, a);
       +    zsetu(r, 1);
       +    zsetu(t, s);
       +
       +    while (zcmp(at, t) > 0) \{
       +        zsub(at, at, t);
       +        zlsh(r, r, t);
       +        zmod(r, r, b);
       +        if (zzero(r))
       +            break;
       +    \}
       +    if (!zzero(a) && !zzero(b)) \{
       +        zlsh(r, r, a);
       +        zmod(r, r, b);
       +    \}
       +
       +    zfree(at), zfree(t);
       +\}
       +\end{alltt}
       +\vspace{-1em}
       +
       +It is worth noting that this function is
       +not necessarily faster than \texttt{zmodpow}.
       +
       +
       +
       +\item \textbf{Modular left-shift, extended}
       +
       +The sign of \texttt{b} shall not effect the
       +result. Use \texttt{zabs} to create a copy
       +of \texttt{b} with its absolute value.
       +
       +
       +
       +\item \textbf{The totient}
       +
       +\( \displaystyle{
       +    \varphi(n)
       +    = n \prod_{p \in \textbf{P} : p | n} \left ( 1 - \frac{1}{p} \right )
       +    = n \prod_{p \in \textbf{P} : p | n} \left ( \frac{p - 1}{p} \right )
       +}\)
       +
       +\noindent
       +So, if we set $a = n$ and $b = 1$, then we iterate
       +of all integers $p$, $2 \le p < n$. For which $p$
       +that is prime, we set $a \gets a \cdot (p - 1)$ and
       +$b \gets b \cdot p$. After the iteration, $b | a$,
       +and $\varphi(n) = \frac{a}{b}$.
       +