Modular arithmetic
This commit is contained in:
parent
d348ef22ce
commit
6b3dd3d57f
164
luku21.tex
164
luku21.tex
|
@ -372,21 +372,23 @@ by the formula
|
||||||
For example, $\varphi(12)=2^1 \cdot (2-1) \cdot 3^0 \cdot (3-1)=4$.
|
For example, $\varphi(12)=2^1 \cdot (2-1) \cdot 3^0 \cdot (3-1)=4$.
|
||||||
Note that $\varphi(n)=n-1$ if $n$ is prime.
|
Note that $\varphi(n)=n-1$ if $n$ is prime.
|
||||||
|
|
||||||
\section{Modulolaskenta}
|
\section{Modular arithmetic}
|
||||||
|
|
||||||
\index{modulolaskenta@modulolaskenta}
|
\index{modular arithmetic}
|
||||||
|
|
||||||
\key{Modulolaskennassa} lukualuetta rajoitetaan
|
In \key{modular arithmetic},
|
||||||
niin, että käytössä ovat vain
|
the set of available numbers is restricted so
|
||||||
kokonaisluvut $0,1,2,\ldots,m-1$,
|
that only numbers $0,1,2,\ldots,m-1$ can be used
|
||||||
missä $m$ on vakio.
|
where $m$ is a constant.
|
||||||
Ideana on, että lukua $x$ vastaa luku $x \bmod m$
|
Each number $x$ is
|
||||||
eli luvun $x$ jakojäännös luvulla $m$.
|
represented by the number $x \bmod m$:
|
||||||
Esimerkiksi jos $m=17$, niin lukua $75$ vastaa luku
|
the remainder after dividing $x$ by $m$.
|
||||||
$75 \bmod 17 = 7$.
|
For example, if $m=17$, then $75$
|
||||||
|
is represented by $75 \bmod 17 = 7$.
|
||||||
|
|
||||||
Useissa laskutoimituksissa jakojäännöksen voi laskea
|
Often we can take the remainder before doing a
|
||||||
ennen laskutoimitusta, minkä ansiosta saadaan seuraavat kaavat:
|
calculation.
|
||||||
|
In particular, the following formulas can be used:
|
||||||
\[
|
\[
|
||||||
\begin{array}{rcl}
|
\begin{array}{rcl}
|
||||||
(x+y) \bmod m & = & (x \bmod m + y \bmod m) \bmod m \\
|
(x+y) \bmod m & = & (x \bmod m + y \bmod m) \bmod m \\
|
||||||
|
@ -396,125 +398,119 @@ ennen laskutoimitusta, minkä ansiosta saadaan seuraavat kaavat:
|
||||||
\end{array}
|
\end{array}
|
||||||
\]
|
\]
|
||||||
|
|
||||||
\subsubsection{Tehokas potenssilasku}
|
\subsubsection{Modular exponentiation}
|
||||||
|
|
||||||
Modulolaskennassa tulee usein tarvetta laskea
|
|
||||||
tehokkaasti potenssilasku $x^n$.
|
Often there is need to efficiently calculate
|
||||||
Tämä onnistuu ajassa $O(\log n)$
|
the remainder of $x^n$.
|
||||||
seuraavan rekursion avulla:
|
This can be done in $O(\log n)$ time
|
||||||
|
using the following recursion:
|
||||||
\begin{equation*}
|
\begin{equation*}
|
||||||
x^n = \begin{cases}
|
x^n = \begin{cases}
|
||||||
1 & n = 0\\
|
1 & n = 0\\
|
||||||
x^{n/2} \cdot x^{n/2} & \text{$n$ on parillinen}\\
|
x^{n/2} \cdot x^{n/2} & \text{$n$ is even}\\
|
||||||
x^{n-1} \cdot x & \text{$n$ on pariton}
|
x^{n-1} \cdot x & \text{$n$ is odd}
|
||||||
\end{cases}
|
\end{cases}
|
||||||
\end{equation*}
|
\end{equation*}
|
||||||
|
|
||||||
Oleellista on, että parillisen $n$:n
|
It's important that in the case of an even $n$,
|
||||||
tapauksessa luku $x^{n/2}$ lasketaan vain kerran.
|
the number $x^{n/2}$ is calculated only once.
|
||||||
Tämän ansiosta potenssilaskun aikavaativuus on $O(\log n)$,
|
This guarantees that the time complexity of the
|
||||||
koska $n$:n koko puolittuu aina silloin,
|
algorithm is $O(\log n)$ because $n$ is always halved
|
||||||
kun $n$ on parillinen.
|
when it is even.
|
||||||
|
|
||||||
Seuraava funktio laskee luvun $x^n \bmod m$:
|
The following function calculates the number
|
||||||
|
$x^n \bmod m$:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
int pot(int x, int n, int m) {
|
int modpow(int x, int n, int m) {
|
||||||
if (n == 0) return 1%m;
|
if (n == 0) return 1%m;
|
||||||
int u = pot(x,n/2,m);
|
int u = modpow(x,n/2,m);
|
||||||
u = (u*u)%m;
|
u = (u*u)%m;
|
||||||
if (n%2 == 1) u = (u*x)%m;
|
if (n%2 == 1) u = (u*x)%m;
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
\subsubsection{Fermat'n pieni lause ja Eulerin lause}
|
\subsubsection{Fermat's theorem and Euler's theorem}
|
||||||
|
|
||||||
\index{Fermat'n pieni lause}
|
\index{Fermat's theorem}
|
||||||
\index{Eulerin lause@Eulerin lause}
|
\index{Euler's theorem}
|
||||||
|
|
||||||
\key{Fermat'n pienen lauseen} mukaan
|
\key{Fermat's theorem} states that
|
||||||
\[x^{m-1} \bmod m = 1,\]
|
\[x^{m-1} \bmod m = 1,\]
|
||||||
kun $m$ on alkuluku ja $x$ ja $m$ ovat suhteelliset alkuluvut.
|
when $m$ is prime and $x$ and $m$ are coprime.
|
||||||
Tällöin myös
|
This also yields
|
||||||
\[x^k \bmod m = x^{k \bmod (m-1)} \bmod m.\]
|
\[x^k \bmod m = x^{k \bmod (m-1)} \bmod m.\]
|
||||||
Yleisemmin \key{Eulerin lauseen} mukaan
|
More generally, \key{Euler's theorem} states that
|
||||||
\[x^{\varphi(m)} \bmod m = 1,\]
|
\[x^{\varphi(m)} \bmod m = 1,\]
|
||||||
kun $x$ ja $m$ ovat suhteelliset alkuluvut.
|
when $x$ and $m$ are coprime.
|
||||||
Fermat'n pieni lause seuraa Eulerin lauseesta,
|
Fermat's theorem follows from Euler's theorem,
|
||||||
koska jos $m$ on alkuluku, niin $\varphi(m)=m-1$.
|
because if $m$ is a prime, then $\varphi(m)=m-1$.
|
||||||
|
|
||||||
\subsubsection{Modulon käänteisluku}
|
\subsubsection{Modular inverse}
|
||||||
|
|
||||||
\index{modulon kxxnteisluku@modulon käänteisluku}
|
\index{modular inverse}
|
||||||
|
|
||||||
Luvun $x$ käänteisluku modulo $m$
|
The modular inverse of $x$ modulo $m$
|
||||||
tarkoittaa sellaista lukua $x^{-1}$,
|
is a number $x^{-1}$ such that
|
||||||
että
|
|
||||||
\[ x x^{-1} \bmod m = 1. \]
|
\[ x x^{-1} \bmod m = 1. \]
|
||||||
Esimerkiksi jos $x=6$ ja $m=17$,
|
For example, if $x=6$ and $m=17$,
|
||||||
niin $x^{-1}=3$, koska $6\cdot3 \bmod 17=1$.
|
then $x^{-1}=3$, because $6\cdot3 \bmod 17=1$.
|
||||||
|
|
||||||
Modulon käänteisluku mahdollistaa
|
Using modular inverses, we can do divisions
|
||||||
jakolaskun laskemisen modulossa,
|
for remainders, because division by $x$
|
||||||
koska jakolasku luvulla $x$ vastaa
|
corresponds to multiplication by $x^{-1}$.
|
||||||
kertolaskua luvulla $x^{-1}$.
|
For example, to evaluate the value of $36/6 \bmod 17$,
|
||||||
Esimerkiksi jos haluamme laskea
|
we can use the formula $2 \cdot 3 \bmod 17$,
|
||||||
jakolaskun $36/6 \bmod 17$,
|
because $36 \bmod 17 = 2$ and $6^{-1} \bmod 17 = 3$.
|
||||||
voimme muuttaa sen muotoon $2 \cdot 3 \bmod 17$,
|
|
||||||
koska $36 \bmod 17 = 2$ ja $6^{-1} \bmod 17 = 3$.
|
|
||||||
|
|
||||||
Modulon käänteislukua ei
|
However, a modular inverse doesn't always exist.
|
||||||
kuitenkaan ole aina olemassa.
|
For example, if $x=2$ and $m=4$, the equation
|
||||||
Esimerkiksi jos $x=2$ ja $m=4$,
|
|
||||||
yhtälölle
|
|
||||||
\[ x x^{-1} \bmod m = 1. \]
|
\[ x x^{-1} \bmod m = 1. \]
|
||||||
ei ole ratkaisua, koska kaikki luvun 2
|
can't be solved, because all multiples of the number 2
|
||||||
moninkerrat ovat parillisia eikä jakojäännös
|
are even, and the remainder can never be 1.
|
||||||
4:llä voi koskaan olla 1.
|
It turns out that the number $x^{-1} \bmod m$ exists
|
||||||
Osoittautuu, että $x^{-1} \bmod m$
|
exactly when $x$ and $m$ are coprime.
|
||||||
on olemassa tarkalleen silloin,
|
|
||||||
kun $x$ ja $m$ ovat suhteelliset alkuluvut.
|
|
||||||
|
|
||||||
Jos modulon käänteisluku on olemassa,
|
If a modular inverse exists, it can be
|
||||||
sen saa laskettua kaavalla
|
calculated using the formula
|
||||||
\[
|
\[
|
||||||
x^{-1} = x^{\varphi(m)-1}.
|
x^{-1} = x^{\varphi(m)-1}.
|
||||||
\]
|
\]
|
||||||
Erityisesti jos $m$ on alkuluku, kaavasta tulee
|
If $m$ is prime, the formula becomes
|
||||||
\[
|
\[
|
||||||
x^{-1} = x^{m-2}.
|
x^{-1} = x^{m-2}.
|
||||||
\]
|
\]
|
||||||
Esimerkiksi jos $x=6$ ja $m=17$, niin
|
For example, if $x=6$ and $m=17$, then
|
||||||
\[x^{-1}=6^{17-2} \bmod 17 = 3.\]
|
\[x^{-1}=6^{17-2} \bmod 17 = 3.\]
|
||||||
Tämän kaavan ansiosta modulon käänteisluvun pystyy
|
Using this formula, we can calculate the modular inverse
|
||||||
laskemaan nopeasti tehokkaan potenssilaskun avulla.
|
efficiently using the modular exponentation algorithm.
|
||||||
|
|
||||||
Modulon käänteisluvun kaavan voi perustella Eulerin lauseen avulla.
|
The above formula can be derived using Euler's theorem.
|
||||||
Ensinnäkin käänteisluvulle täytyy päteä
|
First, the modular inverse should satisfy the following equation:
|
||||||
\[
|
\[
|
||||||
x x^{-1} \bmod m = 1.
|
x x^{-1} \bmod m = 1.
|
||||||
\]
|
\]
|
||||||
Toisaalta Eulerin lauseen mukaan
|
On the other hand, according to Euler's theorem,
|
||||||
\[
|
\[
|
||||||
x^{\varphi(m)} \bmod m = xx^{\varphi(m)-1} \bmod m = 1,
|
x^{\varphi(m)} \bmod m = xx^{\varphi(m)-1} \bmod m = 1,
|
||||||
\]
|
\]
|
||||||
joten lukujen $x^{-1}$ ja $x^{\varphi(m)-1}$ on oltava samat.
|
so the numbers $x^{-1}$ and $x^{\varphi(m)-1}$ are equal.
|
||||||
|
|
||||||
\subsubsection{Modulot tietokoneessa}
|
\subsubsection{Computer arithmetic}
|
||||||
|
|
||||||
Tietokone käsittelee etumerkittömiä kokonaislukuja
|
In a computers, unsigned integers are represented modulo $2^k$
|
||||||
modulo $2^k$, missä $k$ on luvun bittien määrä.
|
where $k$ is the number of bits.
|
||||||
Usein näkyvä seuraus tästä on luvun arvon pyörähtäminen
|
A usual consequence of this is that a number wraps around
|
||||||
ympäri, jos luku kasvaa liian suureksi.
|
if it becomes too large.
|
||||||
|
|
||||||
Esimerkiksi C++:ssa \texttt{unsigned int} -tyyppinen
|
For example, in C++, numbers of type \texttt{unsigned int}
|
||||||
arvo lasketaan modulo $2^{32}$.
|
are represented modulo $2^{32}$.
|
||||||
Seuraava koodi määrittelee muuttujan
|
The following code defines an \texttt{unsigned int}
|
||||||
tyyppiä \texttt{unsigned int},
|
variable whose value is $123456789$.
|
||||||
joka saa arvon $123456789$.
|
After this, the value will be multiplied by itself,
|
||||||
Sitten muuttujan arvo kerrotaan itsellään,
|
and the result is
|
||||||
jolloin tuloksena on luku
|
|
||||||
$123456789^2 \bmod 2^{32} = 2537071545$.
|
$123456789^2 \bmod 2^{32} = 2537071545$.
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
|
|
Loading…
Reference in New Issue