数论研究整数的结构,也是计算机科学里一块真正用得上的基石。它可以追溯到古代文明对计数的兴趣,但作为独立学科,通常从欧几里得的《几何原本》算起:素数无穷多、整除的基本性质,至今仍是数论的中心事实。自然数尤其是素数(所有大于 1 1 1 的整数的“积木”)的性质,吸引了历代数学家。后来领域扩到素数分布、丢番图方程、模运算,以及黎曼 zeta 一类的数论函数。从整除与素数出发,数论长成了数学里非常活跃的一支,应用从密码学一直延伸到动力系统。
整除性与模运算
先讲整除,是因为它撑起算术基本定理、最大公因数、最小公倍数、模运算,以及许多初等密码构造。讨论整数解、环与域的结构时,也会反复碰到同一套语言。
除法与整除
要谈整除 ,先把除法 说清楚。小学里的除法是把一个数分成若干份,例如 6 ÷ 2 = 3 6\div2=3 6 ÷ 2 = 3 ,6 ÷ 4 = 1.5 6\div4=1.5 6 ÷ 4 = 1.5 。有时商是整数,有时不是。定义如下。
定义 商与余数
用非零数 b b b 去除 a a a ,记作 a ÷ b a \div b a ÷ b 或 a b \frac{a}{b} b a ,得到商 q q q ,以及可能出现的余数 r r r 。运算写成
a = b × q + r , a = b \times q + r, a = b × q + r , 其中 0 ≤ r < b 0 \leq r < b 0 ≤ r < b 且 q ∈ Z q \in \mathbb{Z} q ∈ Z 。
6 ÷ 2 = 3 6\div2=3 6 ÷ 2 = 3 时,6 = 2 × 3 + 0 6=2\times3+0 6 = 2 × 3 + 0 ,于是 r = 0 r=0 r = 0 、q = 3 q=3 q = 3 。6 ÷ 4 6\div4 6 ÷ 4 若做整数除法,则 6 = 4 × 1 + 2 6=4\times1+2 6 = 4 × 1 + 2 ,即 q = 1 q=1 q = 1 、r = 2 r=2 r = 2 ;若做实数除法,则 6 / 4 = 1.5 6/4=1.5 6/4 = 1.5 。下面把这两种运算分开。
定义 实数除法
实数除法把余数并进商的小数部分。用 b b b 除 a a a 时,商 q q q 是实数
q = a b . q = \frac{a}{b}. q = b a .
实数除法没有单独的余数,因为它关心的是“每份有多大”。整数除法关心的是整除关系与余数,这正是本章后面的主题。
有了两种除法,整除就好说了。
定义 整除
设 a a a 、b b b 为整数且 a ≠ 0 a\neq 0 a = 0 。若存在整数 c c c 使得 b = a × c b=a\times c b = a × c ,就称 a a a 整除 b b b 。等价说法是 b / a b/a b / a 为整数。此时称 a a a 是 b b b 的因数或约数,b b b 是 a a a 的倍数。记号 a ∣ b a\mid b a ∣ b 表示 a a a 整除 b b b ;a ∤ b a\nmid b a ∤ b 表示 a a a 不整除 b b b 。
例如 4 ∣ 20 4\mid 20 4 ∣ 20 ,因为 20 ÷ 4 20\div4 20 ÷ 4 是整数;但 4 ∤ 21 4\nmid 21 4 ∤ 21 。用存在量词写就是 a ∣ b ⟺ ∃ c ( a c = b ) a\mid b \iff \exists c\,(ac=b) a ∣ b ⟺ ∃ c ( a c = b ) 。
问题 不超过 n n n 且被 d d d 整除的正整数个数 设 n n n 和 d d d 是正整数。有多少个不超过 n n n 的正整数能被 d d d 整除?
被 d d d 整除的正整数都形如 d k dk d k ,其中 k k k 是正整数。于是不超过 n n n 且被 d d d 整除的正整数个数,等于满足 0 < d k ≤ n 0<dk\le n 0 < d k ≤ n 的整数 k k k 的个数,也就是 0 < k ≤ n / d 0<k\le n/d 0 < k ≤ n / d 的个数。因此答案是 ⌊ n / d ⌋ \left\lfloor n/d \right\rfloor ⌊ n / d ⌋ 。
整除有下面几条性质,都可以直接证明。
定理 整除的基本性质
设 a a a 、b b b 、c c c 为整数,且 a ≠ 0 a\neq 0 a = 0 。则:
若 a ∣ b a \mid b a ∣ b 且 a ∣ c a \mid c a ∣ c ,则 a ∣ ( b + c ) a \mid (b+c) a ∣ ( b + c ) ;
若 a ∣ b a \mid b a ∣ b ,则对任意整数 c c c 都有 a ∣ b c a \mid bc a ∣ b c ;
若 a ∣ b a \mid b a ∣ b 且 b ∣ c b\mid c b ∣ c ,则 a ∣ c a \mid c a ∣ c 。
证明
由 a ∣ b a \mid b a ∣ b 与 a ∣ c a \mid c a ∣ c ,存在整数 m m m 、n n n 使得 b = a m b=am b = am 、c = a n c=an c = an 。于是 b + c = a m + a n = a ( m + n ) b+c=am+an=a(m+n) b + c = am + an = a ( m + n ) ,m + n m+n m + n 是整数,故 a ∣ ( b + c ) a\mid(b+c) a ∣ ( b + c ) 。
由 a ∣ b a\mid b a ∣ b ,存在整数 k k k 使得 b = a k b=ak b = ak 。对任意整数 c c c ,b c = a ( k c ) bc=a(kc) b c = a ( k c ) ,k c kc k c 是整数,故 a ∣ b c a\mid bc a ∣ b c 。
由 a ∣ b a\mid b a ∣ b 且 b ∣ c b\mid c b ∣ c ,存在整数 p p p 、q q q 使得 b = a p b=ap b = a p 、c = b q c=bq c = b q 。代入得 c = ( a p ) q = a ( p q ) c=(ap)q=a(pq) c = ( a p ) q = a ( pq ) ,p q pq pq 是整数,故 a ∣ c a\mid c a ∣ c 。
由此立刻得到线性组合仍被整除。
推论 线性组合的整除
设 a a a 、b b b 、c c c 为整数且 a ≠ 0 a\neq 0 a = 0 。若 a ∣ b a\mid b a ∣ b 且 a ∣ c a\mid c a ∣ c ,则对任意整数 m m m 、n n n 都有 a ∣ m b + n c a\mid mb+nc a ∣ mb + n c 。
证明
写 b = a u b=au b = a u 、c = a v c=av c = a v ,其中 u , v u,v u , v 为整数。则 m b + n c = a ( m u + n v ) mb+nc=a(mu+nv) mb + n c = a ( m u + n v ) ,括号内仍是整数,故得证。
模运算
这一小节盯住余数,也就是模运算。除法定义里已经出现商 q q q 和余数 r r r ,下面用专门记号写出它们。
记号 商运算与余数运算
对 a a a 、b b b ,由 a = b × q + r a = b\times q + r a = b × q + r 规定
q = a div b , q = a\ \textbf{div}\ b, q = a div b , r = a mod b . r = a\ \textbf{mod}\ b. r = a mod b .
当 a a a 是整数、b b b 是正整数时,a div b = ⌊ a / b ⌋ a\ \textbf{div}\ b = \left \lfloor a/b \right \rfloor a div b = ⌊ a / b ⌋ 。
93 = 9 × 10 + 3 93 = 9\times 10 + 3 93 = 9 × 10 + 3 ,所以 q = 10 q = 10 q = 10 ,r = 3 r = 3 r = 3 。
商:93 div 9 = 10 = ⌊ 93 / 9 ⌋ = ⌊ 10.3333 … ⌋ = 10 93\ \textbf{div}\ 9 = 10 = \lfloor93/9\rfloor = \lfloor10.3333\dots \rfloor = 10 93 div 9 = 10 = ⌊ 93/9 ⌋ = ⌊ 10.3333 … ⌋ = 10 。
余数:93 mod 9 = 3 = 93 − 90 93\ \textbf{mod}\ 9 = 3 = 93 - 90 93 mod 9 = 3 = 93 − 90 。
− 93 -93 − 93 除以 9 9 9 的商和余数各是多少?
− 93 = 9 × ( − 11 ) + 6 -93 = 9\times (-11) + 6 − 93 = 9 × ( − 11 ) + 6 ,所以 q = − 11 q = -11 q = − 11 ,r = 6 r = 6 r = 6 。
必须保证 r ≥ 0 r\ge 0 r ≥ 0 。虽然也可以写 − 93 = 9 × ( − 10 ) − 3 -93 = 9\times(-10) - 3 − 93 = 9 × ( − 10 ) − 3 ,但这里的余数约定非负。别的除法算法允许负余数,习题里会碰到。
记号 a mod m a\ \textbf{mod}\ m a mod m 表示用正整数 m m m 除整数 a a a 所得余数。下面引入一个相关但不同的记号:用同一个正整数去除两个整数,余数相同。为什么要关心“除以同一个正整数后余数一样”的数?这是数论的基本课题,后面会看出用处。
设 a a a 、b b b 为整数,m m m 为正整数。若 m m m 整除 a − b a-b a − b ,则称 a a a 模 m m m 同余于 b b b ,记作 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) 。这个关系叫做同余,m m m 叫做模。若不同余,则写 a ≢ b ( m o d m ) a \not\equiv b \pmod{m} a ≡ b ( mod m ) 。
注意 m o d \bmod mod 与 mod \textbf{mod} mod 不是同一个符号:前者是整数上的关系,后者是求余函数。二者有联系。
定理 同余与余数
设 a a a 、b b b 为整数,m m m 为正整数。则 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) 当且仅当 a mod m = b mod m a\ \textbf{mod}\ m = b\ \textbf{mod}\ m a mod m = b mod m 。
证明
先设 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) 。按定义,m m m 整除 a − b a-b a − b ,即存在整数 k k k 使得 a − b = k m a-b=km a − b = k m 。
用 m m m 除 a a a 和 b b b ,二者留下同一个余数 r r r :因为 a = q 1 m + r a=q_1m+r a = q 1 m + r 、b = q 2 m + r b=q_2m+r b = q 2 m + r ,而 a − b a-b a − b 是 m m m 的倍数,不改变余数。
反过来,若 a m o d m = b m o d m a \bmod m = b \bmod m a mod m = b mod m ,则用 m m m 去除二者时余数相同,记这个余数为 r r r 。于是 a = q 1 m + r a=q_1m+r a = q 1 m + r 、b = q 2 m + r b=q_2m+r b = q 2 m + r 。相减得 a − b = ( q 1 − q 2 ) m a-b=(q_1-q_2)m a − b = ( q 1 − q 2 ) m ,即 m m m 整除 a − b a-b a − b ,故 a ≡ b ( m o d m ) a\equiv b\pmod{m} a ≡ b ( mod m ) 。
定理 同余的差形式
设 m m m 为正整数。整数 a a a 与 b b b 模 m m m 同余,当且仅当存在整数 k k k 使得 a = b + k m a=b+km a = b + k m 。
证明与上一条类似,习题里完成。
定理 同余对加法和乘法封闭
设 m m m 为正整数。若 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) 且 c ≡ d ( m o d m ) c \equiv d \pmod{m} c ≡ d ( mod m ) ,则 a + c ≡ b + d ( m o d m ) a + c \equiv b + d \pmod{m} a + c ≡ b + d ( mod m ) 且 a c ≡ b d ( m o d m ) ac \equiv bd \pmod{m} a c ≡ b d ( mod m ) 。
证明
由 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) 与 c ≡ d ( m o d m ) c \equiv d \pmod{m} c ≡ d ( mod m ) ,存在整数 s s s 、t t t 使得 b = a + s m b=a+sm b = a + s m 、d = c + t m d=c+tm d = c + t m 。于是
b + d = ( a + s m ) + ( c + t m ) = ( a + c ) + m ( s + t ) , b + d = (a + sm) + (c + tm) = (a + c) + m(s + t), b + d = ( a + s m ) + ( c + t m ) = ( a + c ) + m ( s + t ) , b d = ( a + s m ) ( c + t m ) = a c + m ( a t + c s + s t m ) . bd = (a + sm)(c + tm) = ac + m(at + cs + stm). b d = ( a + s m ) ( c + t m ) = a c + m ( a t + cs + s t m ) . 因此 a + c ≡ b + d ( m o d m ) a + c \equiv b + d \pmod{m} a + c ≡ b + d ( mod m ) 且 a c ≡ b d ( m o d m ) ac \equiv bd \pmod{m} a c ≡ b d ( mod m ) 。
由 7 ≡ 2 ( m o d 5 ) 7 \equiv 2 \pmod{5} 7 ≡ 2 ( mod 5 ) 与 11 ≡ 1 ( m o d 5 ) 11 \equiv 1 \pmod{5} 11 ≡ 1 ( mod 5 ) ,得到 18 = 7 + 11 ≡ 2 + 1 = 3 ( m o d 5 ) 18 = 7 + 11 \equiv 2 + 1 = 3 \pmod{5} 18 = 7 + 11 ≡ 2 + 1 = 3 ( mod 5 ) ,以及 77 = 7 ⋅ 11 ≡ 2 ⋅ 1 = 2 ( m o d 5 ) 77 = 7 \cdot 11 \equiv 2 \cdot 1 = 2 \pmod{5} 77 = 7 ⋅ 11 ≡ 2 ⋅ 1 = 2 ( mod 5 ) 。
推论 先取模再运算
设 m m m 为正整数,a a a 、b b b 为整数。则
( a + b ) m o d m = ( ( a m o d m ) + ( b m o d m ) ) m o d m , (a + b) \bmod m = ((a \bmod m) + (b \bmod m)) \bmod m, ( a + b ) mod m = (( a mod m ) + ( b mod m )) mod m , a b m o d m = ( ( a m o d m ) ( b m o d m ) ) m o d m . ab \bmod m = ((a \bmod m)(b \bmod m)) \bmod m. ab mod m = (( a mod m ) ( b mod m )) mod m .
证明
按 m o d \bmod mod 与同余的定义,a ≡ ( a m o d m ) ( m o d m ) a \equiv (a \bmod m) \pmod{m} a ≡ ( a mod m ) ( mod m ) ,b ≡ ( b m o d m ) ( m o d m ) b \equiv (b \bmod m) \pmod{m} b ≡ ( b mod m ) ( mod m ) 。于是 a + b ≡ ( a m o d m ) + ( b m o d m ) ( m o d m ) a + b \equiv (a \bmod m) + (b \bmod m) \pmod{m} a + b ≡ ( a mod m ) + ( b mod m ) ( mod m ) ,且 a b ≡ ( a m o d m ) ( b m o d m ) ( m o d m ) ab \equiv (a \bmod m)(b \bmod m) \pmod{m} ab ≡ ( a mod m ) ( b mod m ) ( mod m ) 。推论中的等式由这两条同余立刻得到。
在集合 Z m = { 0 , 1 , … , m − 1 } \mathbb{Z}_m=\{0,1,\ldots,m-1\} Z m = { 0 , 1 , … , m − 1 } 上可以定义算术。加法 ⊕ m \oplus_m ⊕ m 规定为
a ⊕ m b = ( a + b ) m o d m , a \oplus_m b = (a + b) \bmod m, a ⊕ m b = ( a + b ) mod m ,
右边是普通整数加法;乘法 ⊙ m \odot_m ⊙ m 规定为
a ⊙ m b = ( a ⋅ b ) m o d m , a \odot_m b = (a \cdot b) \bmod m, a ⊙ m b = ( a ⋅ b ) mod m ,
右边是普通整数乘法。这两个运算叫做模 m m m 加法和模 m m m 乘法,使用它们就是在做模 m m m 算术。
例 在 Z 11 \mathbb{Z}_{11} Z 11 里计算 用 Z m \mathbb{Z}_m Z m 中的定义求 7 ⊕ 11 9 7 \oplus_{11} 9 7 ⊕ 11 9 和 7 ⊙ 11 9 7 \odot_{11} 9 7 ⊙ 11 9 。
按模 11 11 11 加法,
7 ⊕ 11 9 = ( 7 + 9 ) m o d 11 = 16 m o d 11 = 5 , 7 \oplus_{11} 9 = (7 + 9) \bmod 11 = 16 \bmod 11 = 5, 7 ⊕ 11 9 = ( 7 + 9 ) mod 11 = 16 mod 11 = 5 , 7 ⊙ 11 9 = ( 7 ⋅ 9 ) m o d 11 = 63 m o d 11 = 8. 7 \odot_{11} 9 = (7 \cdot 9) \bmod 11 = 63 \bmod 11 = 8. 7 ⊙ 11 9 = ( 7 ⋅ 9 ) mod 11 = 63 mod 11 = 8. 因此 7 ⊕ 11 9 = 5 7 \oplus_{11} 9 = 5 7 ⊕ 11 9 = 5 ,7 ⊙ 11 9 = 8 7 \odot_{11} 9 = 8 7 ⊙ 11 9 = 8 。
习题
练习 证明线性组合的整除
证明:若 a a a 、b b b 、c c c 为整数且 a ≠ 0 a\neq 0 a = 0 ,a ∣ b a\mid b a ∣ b 且 a ∣ c a\mid c a ∣ c ,则对任意整数 m m m 、n n n 都有 a ∣ m b + n c a\mid mb+nc a ∣ mb + n c 。
证明
由整除的基本性质第二条,a ∣ b a\mid b a ∣ b 给出 a ∣ m b a\mid mb a ∣ mb ,a ∣ c a\mid c a ∣ c 给出 a ∣ n c a\mid nc a ∣ n c 。再由第一条,a ∣ ( m b + n c ) a\mid(mb+nc) a ∣ ( mb + n c ) 。
练习 证明同余的差形式
证明:整数 a a a 与 b b b 模 m m m 同余,当且仅当存在整数 k k k 使得 a = b + k m a=b+km a = b + k m 。可以用本章其他定理。
证明
若 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) ,则 m ∣ ( a − b ) m\mid(a-b) m ∣ ( a − b ) ,故存在整数 k k k 使得 a = b + k m a=b+km a = b + k m 。反过来,若存在整数 k k k 使得 a = b + k m a=b+km a = b + k m ,则 k m = a − b km=a-b k m = a − b ,于是 m ∣ ( a − b ) m\mid(a-b) m ∣ ( a − b ) ,即 a ≡ b ( m o d m ) a\equiv b\pmod{m} a ≡ b ( mod m ) 。
练习 由 a c ∣ b c ac\mid bc a c ∣ b c 推出 a ∣ b a\mid b a ∣ b 设 a , b , c ∈ Z + a,b,c\in\mathbb{Z}^{+} a , b , c ∈ Z + ,a , c ≠ 0 a,c\neq 0 a , c = 0 ,且 a c ∣ b c ac\mid bc a c ∣ b c 。证明 a ∣ b a\mid b a ∣ b 。
证明
a c ∣ b c ac\mid bc a c ∣ b c 表示存在整数 k k k 使得 b c = k ( a c ) bc=k(ac) b c = k ( a c ) ,从而 b = k a b=ka b = k a ,即 a ∣ b a\mid b a ∣ b 。
证明:若 a a a 、b b b 为整数且 a a a 整除 b b b ,则 a a a 是奇数或 b b b 是偶数。
证明
用逆否。设 a a a 为偶数且 b b b 为奇数,并假设 a ∣ b a\mid b a ∣ b 。则存在整数 k k k 使得 b = k a b=ka b = k a 。令 a = 2 n a=2n a = 2 n 、b = 2 m + 1 b=2m+1 b = 2 m + 1 (原稿把奇数写成与 a a a 共用同一个 n n n ,这里分开写以免混淆),则 2 m + 1 = k ⋅ 2 n 2m+1=k\cdot 2n 2 m + 1 = k ⋅ 2 n ,于是 k = ( 2 m + 1 ) / ( 2 n ) k=(2m+1)/(2n) k = ( 2 m + 1 ) / ( 2 n ) 不是整数,与 k ∈ Z k\in\mathbb{Z} k ∈ Z 矛盾。故原命题成立。
练习 证明 4 ∤ ( a 2 + 2 ) 4\nmid(a^2+2) 4 ∤ ( a 2 + 2 ) 证明:若 a a a 是正整数,则 4 ∤ ( a 2 + 2 ) 4\nmid (a^2+2) 4 ∤ ( a 2 + 2 ) 。
证明
任意正整数 a a a 必取下列四种形式之一,其中 n n n 为整数:a = 4 n a=4n a = 4 n ,a = 4 n + 1 a=4n+1 a = 4 n + 1 ,a = 4 n + 2 a=4n+2 a = 4 n + 2 ,a = 4 n + 3 a=4n+3 a = 4 n + 3 。分别看 a 2 a^2 a 2 模 4 4 4 :
( 4 n ) 2 = 16 n 2 = 4 ⋅ 4 n 2 ≡ 0 ( m o d 4 ) , ( 4 n + 1 ) 2 = 16 n 2 + 8 n + 1 = 4 ( 4 n 2 + 2 n ) + 1 ≡ 1 ( m o d 4 ) , ( 4 n + 2 ) 2 = 16 n 2 + 16 n + 4 = 4 ( 4 n 2 + 4 n + 1 ) ≡ 0 ( m o d 4 ) , ( 4 n + 3 ) 2 = 16 n 2 + 24 n + 9 = 4 ( 4 n 2 + 6 n + 2 ) + 1 ≡ 1 ( m o d 4 ) . \begin{aligned}
(4n)^2 &= 16n^2 = 4 \cdot 4n^2 \equiv 0 \pmod{4}, \\
(4n + 1)^2 &= 16n^2 + 8n + 1 = 4(4n^2 + 2n) + 1 \equiv 1 \pmod{4}, \\
(4n + 2)^2 &= 16n^2 + 16n + 4 = 4(4n^2 + 4n + 1) \equiv 0 \pmod{4}, \\
(4n + 3)^2 &= 16n^2 + 24n + 9 = 4(4n^2 + 6n + 2) + 1 \equiv 1 \pmod{4}.
\end{aligned} ( 4 n ) 2 ( 4 n + 1 ) 2 ( 4 n + 2 ) 2 ( 4 n + 3 ) 2 = 16 n 2 = 4 ⋅ 4 n 2 ≡ 0 ( mod 4 ) , = 16 n 2 + 8 n + 1 = 4 ( 4 n 2 + 2 n ) + 1 ≡ 1 ( mod 4 ) , = 16 n 2 + 16 n + 4 = 4 ( 4 n 2 + 4 n + 1 ) ≡ 0 ( mod 4 ) , = 16 n 2 + 24 n + 9 = 4 ( 4 n 2 + 6 n + 2 ) + 1 ≡ 1 ( mod 4 ) . 再加上 2 2 2 :
a 2 + 2 ≡ 2 ( m o d 4 ) 若 a 2 ≡ 0 ( m o d 4 ) , a 2 + 2 ≡ 3 ( m o d 4 ) 若 a 2 ≡ 1 ( m o d 4 ) . \begin{aligned}
a^2 + 2 &\equiv 2 \pmod{4} \quad \text{若 } a^2 \equiv 0 \pmod{4}, \\
a^2 + 2 &\equiv 3 \pmod{4} \quad \text{若 } a^2 \equiv 1 \pmod{4}.
\end{aligned} a 2 + 2 a 2 + 2 ≡ 2 ( mod 4 ) 若 a 2 ≡ 0 ( mod 4 ) , ≡ 3 ( mod 4 ) 若 a 2 ≡ 1 ( mod 4 ) . 两种情形余数都不是 0 0 0 ,故 4 4 4 不能整除 a 2 + 2 a^2+2 a 2 + 2 。
设 a a a 、b b b 为整数,a ≡ 11 ( m o d 19 ) a \equiv 11 \pmod{19} a ≡ 11 ( mod 19 ) ,b ≡ 3 ( m o d 19 ) b \equiv 3 \pmod{19} b ≡ 3 ( mod 19 ) 。求满足 0 ≤ c ≤ 18 0 \leq c \leq 18 0 ≤ c ≤ 18 的整数 c c c ,使得
c ≡ 13 a ( m o d 19 ) c \equiv 13a \pmod{19} c ≡ 13 a ( mod 19 ) ;
c ≡ 8 b ( m o d 19 ) c \equiv 8b \pmod{19} c ≡ 8 b ( mod 19 ) ;
c ≡ a − b ( m o d 19 ) c \equiv a - b \pmod{19} c ≡ a − b ( mod 19 ) ;
c ≡ 7 a + 3 b ( m o d 19 ) c \equiv 7a + 3b \pmod{19} c ≡ 7 a + 3 b ( mod 19 ) ;
c ≡ 2 a 2 + 3 b 2 ( m o d 19 ) c \equiv 2a^2 + 3b^2 \pmod{19} c ≡ 2 a 2 + 3 b 2 ( mod 19 ) ;
c ≡ a 3 + 4 b 3 ( m o d 19 ) c \equiv a^3 + 4b^3 \pmod{19} c ≡ a 3 + 4 b 3 ( mod 19 ) 。
这相当于求右端模 19 19 19 的余数。直接算:
13 ⋅ 11 = 143 ≡ 10 ( m o d 19 ) 13 \cdot 11 = 143 \equiv 10 \pmod{19} 13 ⋅ 11 = 143 ≡ 10 ( mod 19 )
8 ⋅ 3 = 24 ≡ 5 ( m o d 19 ) 8 \cdot 3 = 24 \equiv 5 \pmod{19} 8 ⋅ 3 = 24 ≡ 5 ( mod 19 )
11 − 3 = 8 ( m o d 19 ) 11 - 3 = 8 \pmod{19} 11 − 3 = 8 ( mod 19 )
7 ⋅ 11 + 3 ⋅ 3 = 86 ≡ 10 ( m o d 19 ) 7 \cdot 11 + 3 \cdot 3 = 86 \equiv 10 \pmod{19} 7 ⋅ 11 + 3 ⋅ 3 = 86 ≡ 10 ( mod 19 )
2 ⋅ 11 2 + 3 ⋅ 3 2 = 269 ≡ 3 ( m o d 19 ) 2 \cdot 11^2 + 3 \cdot 3^2 = 269 \equiv 3 \pmod{19} 2 ⋅ 1 1 2 + 3 ⋅ 3 2 = 269 ≡ 3 ( mod 19 )
11 3 + 4 ⋅ 3 3 = 1439 ≡ 14 ( m o d 19 ) 11^3 + 4 \cdot 3^3 = 1439 \equiv 14 \pmod{19} 1 1 3 + 4 ⋅ 3 3 = 1439 ≡ 14 ( mod 19 )
练习 同余则余数相同
设 m m m 为正整数。证明:若 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) ,则 a m o d m = b m o d m a \bmod m = b \bmod m a mod m = b mod m 。
证明
设 a ≡ b ( m o d m ) a \equiv b \pmod{m} a ≡ b ( mod m ) ,则 m ∣ a − b m\mid a-b m ∣ a − b ,即 a − b = m c a-b=mc a − b = m c ,从而 a = b + m c a=b+mc a = b + m c 。令 b = q m + r b=qm+r b = q m + r ,其中 0 ≤ r < m 0\le r<m 0 ≤ r < m (也就是 r = b m o d m r=b\bmod m r = b mod m )。则 a = q m + r + m c = ( q + c ) m + r a=qm+r+mc=(q+c)m+r a = q m + r + m c = ( q + c ) m + r 。按定义,r r r 也等于 a m o d m a\bmod m a mod m 。
练习 同余两边同除以公因数
设 a ≡ b ( m o d n ) a \equiv b \pmod{n} a ≡ b ( mod n ) ,且 d ∣ a d\mid a d ∣ a 、d ∣ b d\mid b d ∣ b 、d ∣ n d\mid n d ∣ n 。证明
a d ≡ b d ( m o d n d ) . \frac{a}{d}\equiv \frac{b}{d} \pmod{\frac{n}{d}}. d a ≡ d b ( mod d n ) .
证明
由 a ≡ b ( m o d n ) a \equiv b \pmod{n} a ≡ b ( mod n ) ,存在整数 k k k 使得 a = b + k n a=b+kn a = b + k n 。又 d ∣ a d\mid a d ∣ a 、d ∣ b d\mid b d ∣ b ,故 a = d m 1 a=dm_1 a = d m 1 、b = d m 2 b=dm_2 b = d m 2 ;由 d ∣ n d\mid n d ∣ n 得 n = d l n=dl n = d l 。代入得 d m 1 = d m 2 + k ( d l ) dm_1=dm_2+k(dl) d m 1 = d m 2 + k ( d l ) 。两边除以 d d d :m 1 = m 2 + k l m_1=m_2+kl m 1 = m 2 + k l ,即
a d = b d + k ( n d ) . \frac{a}{d} = \frac{b}{d} + k \left(\frac{n}{d}\right). d a = d b + k ( d n ) . k ( n / d ) k(n/d) k ( n / d ) 是整数,故 a / d a/d a / d 模 n / d n/d n / d 同余于 b / d b/d b / d 。
练习 证明 8 8 8 整除 2 ( x + y ) 13 + y − 1 2(x+y)^{13}+y-1 2 ( x + y ) 13 + y − 1 设整数 x x x 、y y y 满足 x ≡ 2 ( m o d 8 ) x \equiv 2 \pmod{8} x ≡ 2 ( mod 8 ) 、y ≡ 7 ( m o d 8 ) y \equiv 7 \pmod{8} y ≡ 7 ( mod 8 ) 。证明 8 8 8 整除 2 ( x + y ) 13 + y − 1 2(x + y)^{13} + y - 1 2 ( x + y ) 13 + y − 1 。
证明
先求 x + y x+y x + y 模 8 8 8 :
x + y ≡ 2 + 7 ≡ 9 ≡ 1 ( m o d 8 ) . x + y \equiv 2 + 7 \equiv 9 \equiv 1 \pmod{8}. x + y ≡ 2 + 7 ≡ 9 ≡ 1 ( mod 8 ) . 于是
( x + y ) 13 ≡ 1 13 ≡ 1 ( m o d 8 ) , (x + y)^{13} \equiv 1^{13} \equiv 1 \pmod{8}, ( x + y ) 13 ≡ 1 13 ≡ 1 ( mod 8 ) , 2 ( x + y ) 13 ≡ 2 ⋅ 1 ≡ 2 ( m o d 8 ) , 2(x + y)^{13} \equiv 2 \cdot 1 \equiv 2 \pmod{8}, 2 ( x + y ) 13 ≡ 2 ⋅ 1 ≡ 2 ( mod 8 ) , 2 ( x + y ) 13 + y − 1 ≡ 2 + 7 − 1 ≡ 8 ≡ 0 ( m o d 8 ) . 2(x + y)^{13} + y - 1 \equiv 2 + 7 - 1 \equiv 8 \equiv 0 \pmod{8}. 2 ( x + y ) 13 + y − 1 ≡ 2 + 7 − 1 ≡ 8 ≡ 0 ( mod 8 ) . 故 8 8 8 整除 2 ( x + y ) 13 + y − 1 2(x+y)^{13}+y-1 2 ( x + y ) 13 + y − 1 。
数的表示与算法
日常生活用十进制写整数,但并非处处如此:计时用六十进制。计算机科学里则广泛使用二进制、八进制和十六进制。二进制只有 0 0 0 和 1 1 1 ,正好对应布尔代数里的两个值,也对应集成电路里开关的通断。本节讨论不同进制下的表示及其关系,重点是计算机使用的二进制,并分析若干运算算法。
进制表示与进制转换
无论哪一种进制,整数都可以写成该进制底数的幂的线性组合。
定理 进制展开定理
设 b b b 是大于 1 1 1 的整数。则每个正整数 n n n 都可以唯一地写成
n = a k b k + a k − 1 b k − 1 + ⋯ + a 1 b + a 0 , n=a_{k} b^{k}+a_{k-1} b^{k-1}+\cdots+a_{1} b+a_{0}, n = a k b k + a k − 1 b k − 1 + ⋯ + a 1 b + a 0 , 其中 k k k 是非负整数,a 0 , a 1 , ⋯ , a k a_0, a_1,\cdots, a_k a 0 , a 1 , ⋯ , a k 是小于 b b b 的非负整数,且 a k ≠ 0 a_k \neq 0 a k = 0 。
证明
反复带余除法,得到 n = b q 1 + a 0 n=bq_1+a_0 n = b q 1 + a 0 、q 1 = b q 2 + a 1 q_1=bq_2+a_1 q 1 = b q 2 + a 1 等式,其中 0 ≤ a i < b 0\le a_i<b 0 ≤ a i < b 。因为 b ≥ 2 b\ge2 b ≥ 2 ,正商严格递减,过程必终止。逐层代回便得到所写的展开,最后的非零商给出最高位。证明唯一性时,先模 b b b ,两种展开的 a 0 a_0 a 0 必相同;减去这个数字再除以 b b b ,反复进行,所有位数及最高位都被唯一确定。零单独用数字零表示。
例如 1024 = 1 × 10 3 + 0 × 10 2 + 2 × 10 1 + 4 × 10 0 1024 = 1\times10^3+0\times10^2+2\times10^1+4\times10^0 1024 = 1 × 1 0 3 + 0 × 1 0 2 + 2 × 1 0 1 + 4 × 1 0 0 。底数还限制每一位上能出现的数字:十进制里不能把 10 10 10 写成一位,最大数字是 9 9 9 。一般地,b b b 进制里每一位最大是 b − 1 b-1 b − 1 。因此二进制只有 0 0 0 、1 1 1 ,八进制是 0 0 0 到 7 7 7 ,十六进制是 0 0 0 到 15 15 15 。
标明进制时用下标。
记号 进制下标
用 b _b b 表示数的进制,其中 b b b 是底数。
数本身不随写法改变。把 121 10 121_{10} 12 1 10 换成任何别的进制,它仍然是十进制意义下的 121 121 121 ,只是数字串不同。
二进制、八进制与十六进制
二进制展开 以 2 2 2 为底,每一位是 0 0 0 或 1 1 1 。展开方式和上一小节相同。
例 二进制转十进制
二进制展开为 ( 101011111 ) 2 (101011111)_2 ( 101011111 ) 2 的整数,十进制是多少?
这个数有九位:
( 101011111 ) 2 = 1 × 2 8 + 0 × 2 7 + 1 × 2 6 + 0 × 2 5 + 1 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0 = 351. \begin{aligned}
(101011111)_2
&= 1\times 2^8+0\times 2^7+1\times 2^6+0\times 2^5+1\times 2^4\\
&\qquad +1\times 2^3+1\times 2^2+1\times 2^1+1\times 2^0 \\
&=351.
\end{aligned} ( 101011111 ) 2 = 1 × 2 8 + 0 × 2 7 + 1 × 2 6 + 0 × 2 5 + 1 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0 = 351.
八进制转十进制手续相同。十六进制需要十六个不同数字,通常用 0 0 0 到 9 9 9 以及 A A A 到 F F F ,其中 A A A 到 F F F 依次表示十进制的 10 10 10 到 15 15 15 。
例 十六进制转十进制
求 ( 2 A E 0 B ) 16 (2AE0B)_{16} ( 2 A E 0 B ) 16 的十进制展开。
字母只是把两位十进制数塞进一位:
( 2 A E 0 B ) 16 = 2 × 16 4 + 10 × 16 3 + 14 × 16 2 + 0 × 16 1 + 11 × 16 0 = 175627. (2AE0B)_{16} = 2\times 16^4 + 10\times 16^3 + 14\times 16^2 + 0 \times 16^1 + 11 \times 16^0=175627. ( 2 A E 0 B ) 16 = 2 × 1 6 4 + 10 × 1 6 3 + 14 × 1 6 2 + 0 × 1 6 1 + 11 × 1 6 0 = 175627.
每一位十六进制数字对应四位二进制。例如 ( 1110 0101 ) 2 = ( E 5 ) 16 (1110\,0101)_2 = (E5)_{16} ( 1110 0101 ) 2 = ( E 5 ) 16 ,因为 ( 1110 ) 2 = ( E ) 16 (1110)_2 = (E)_{16} ( 1110 ) 2 = ( E ) 16 、( 0101 ) 2 = ( 5 ) 16 (0101)_2 = (5)_{16} ( 0101 ) 2 = ( 5 ) 16 。一个字节是八位比特串,因此可以用两位十六进制写出。
进制转换
整数的进制转换
已经会在不同进制下写数,怎样从一种进制转到另一种?通用办法是先转回十进制,再转到目标进制。可以做得更直接:构造 n n n 的 b b b 进制展开时,反复用 b b b 去除。先做
n = b q 0 + a 0 , 0 ≤ a 0 < b . n = bq_{0} + a_{0},\qquad 0\le a_{0}<b. n = b q 0 + a 0 , 0 ≤ a 0 < b .
余数 a 0 a_0 a 0 就是 n n n 在 b b b 进制下最右边的一位。再用 b b b 去除 q 0 q_0 q 0 :
q 0 = b q 1 + a 1 , 0 ≤ a 1 < b . q_0 = bq_{1} + a_{1},\qquad 0\le a_{1}<b. q 0 = b q 1 + a 1 , 0 ≤ a 1 < b .
a 1 a_1 a 1 是从右数第二位。一直做到商为零。数字从右到左依次出现。
例 十进制转十六进制
求 ( 177130 ) 10 (177130)_{10} ( 177130 ) 10 的十六进制展开。
177130 = 16 ⋅ 11070 + 10 , 11070 = 16 ⋅ 691 + 14 , 691 = 16 ⋅ 43 + 3 , 43 = 16 ⋅ 2 + 11 , 2 = 16 ⋅ 0 + 2. \begin{aligned}
177130 &= 16 \cdot 11070 + 10,\\
11070 &= 16 \cdot 691 + 14,\\
691 &= 16 \cdot 43 + 3,\\
43 &= 16 \cdot 2 + 11,\\
2 &= 16 \cdot 0 + 2.
\end{aligned} 177130 11070 691 43 2 = 16 ⋅ 11070 + 10 , = 16 ⋅ 691 + 14 , = 16 ⋅ 43 + 3 , = 16 ⋅ 2 + 11 , = 16 ⋅ 0 + 2. 因此 ( 177130 ) 10 = ( 2 B 3 E A ) 16 (177130)_{10} = (2B3EA)_{16} ( 177130 ) 10 = ( 2 B 3 E A ) 16 。
对应伪代码如下。
算法 1 整数进制转换
Require: 非负整数 n n n 与底数 b > 1 b>1 b > 1
Ensure: n n n 在 b b b 进制下的各位数字
1: digits ← \text{digits} \gets digits ← 空列表
2: while n > 0 n > 0 n > 0 do
3: remainder ← n m o d b \text{remainder} \gets n \bmod b remainder ← n mod b
4: 把 remainder \text{remainder} remainder 追加到 digits \text{digits} digits
5: n ← ⌊ n / b ⌋ n \gets \left\lfloor n / b \right\rfloor n ← ⌊ n / b ⌋
6: end while
7: 把 digits \text{digits} digits 反转
8: return digits \text{digits} digits
小数的进制转换
上一算法只处理整数,小数部分要另做。把十进制浮点数转到 b b b 进制的算法如下。
算法 2 浮点进制转换
Require: 非负实数 number \text{number} number 与目标底数 b > 1 b>1 b > 1
Ensure: number \text{number} number 的 b b b 进制表示
1: integerPart ← ⌊ number ⌋ \text{integerPart} \gets \lfloor \text{number} \rfloor integerPart ← ⌊ number ⌋
2: fractionalPart ← number − integerPart \text{fractionalPart} \gets \text{number} - \text{integerPart} fractionalPart ← number − integerPart
3: baseInteger ← \text{baseInteger} \gets baseInteger ← integerPart \text{integerPart} integerPart 的 b b b 进制表示
4: baseFraction ← \text{baseFraction} \gets baseFraction ← 空串
5: while fractionalPart > 0 \text{fractionalPart} > 0 fractionalPart > 0 do
6: fractionalPart ← fractionalPart × b \text{fractionalPart} \gets \text{fractionalPart} \times b fractionalPart ← fractionalPart × b
7: 把 ⌊ fractionalPart ⌋ \lfloor \text{fractionalPart} \rfloor ⌊ fractionalPart ⌋ 追加到 baseFraction \text{baseFraction} baseFraction
8: fractionalPart ← fractionalPart − ⌊ fractionalPart ⌋ \text{fractionalPart} \gets \text{fractionalPart} - \lfloor \text{fractionalPart} \rfloor fractionalPart ← fractionalPart − ⌊ fractionalPart ⌋
9: end while
10: return baseInteger \text{baseInteger} baseInteger 后接 baseFraction \text{baseFraction} baseFraction
例 把 12.375 12.375 12.375 转到二进制 把十进制浮点数 12.375 12.375 12.375 转到二进制。
整数部分:12 10 = 1100 2 12_{10}=1100_2 1 2 10 = 110 0 2 。
小数部分:
0.375 × 2 = 0.75 → 整数部分为 0 , 0.75 × 2 = 1.5 → 整数部分为 1 , 0.5 × 2 = 1 → 整数部分为 1. \begin{aligned}
0.375 \times 2 &= 0.75 \rightarrow \text{整数部分为 }0, \\
0.75 \times 2 &= 1.5 \rightarrow \text{整数部分为 }1, \\
0.5 \times 2 &= 1 \rightarrow \text{整数部分为 }1.
\end{aligned} 0.375 × 2 0.75 × 2 0.5 × 2 = 0.75 → 整数部分为 0 , = 1.5 → 整数部分为 1 , = 1 → 整数部分为 1. 因此 12.375 10 12.375_{10} 12.37 5 10 等于 1100.011 2 1100.011_{2} 1100.01 1 2 。
一个数同时有整数和小数时,两部分分开转换,再拼回去。习题里会见到这类题。
二、八、十六进制之间的转换
二进制、八进制、十六进制之间的转换特别直接。
原因是这些底数都是 2 2 2 的幂:8 = 2 3 8=2^3 8 = 2 3 ,16 = 2 4 16=2^4 16 = 2 4 。
每位八进制数字对应三位二进制,因为 8 = 2 3 8=2^3 8 = 2 3 。
每位十六进制数字对应四位二进制,因为 16 = 2 4 16=2^4 16 = 2 4 。
因此只要按三位或四位分组,不必做复杂的除法。
例 二进制与八、十六进制互转
求 ( 11 1110 1011 1100 ) 2 (11\,1110\,1011\,1100)_2 ( 11 1110 1011 1100 ) 2 的八进制和十六进制展开,以及 ( 765 ) 8 (765)_{8} ( 765 ) 8 和 ( A 8 D ) 16 (A8D)_{16} ( A 8 D ) 16 的二进制展开。
把 ( 11 1110 1011 1100 ) 2 (11\,1110\,1011\,1100)_2 ( 11 1110 1011 1100 ) 2 转成八进制时,从右往左每三位一组,最左边一组若不够三位就在前面补零。各组是 011 011 011 、111 111 111 、010 010 010 、111 111 111 、100 100 100 ,对应 3 3 3 、7 7 7 、2 2 2 、7 7 7 、4 4 4 。因此 ( 11 1110 1011 1100 ) 2 = ( 37274 ) 8 (11\,1110\,1011\,1100)_2 = (37274)_8 ( 11 1110 1011 1100 ) 2 = ( 37274 ) 8 。
十六进制同样处理,每四位一组:0011 0011 0011 、1110 1110 1110 、1011 1011 1011 、1100 1100 1100 ,对应 3 3 3 、E E E 、B B B 、C C C 。因此 ( 11 1110 1011 1100 ) 2 = ( 3 E B C ) 16 (11\,1110\,1011\,1100)_2 = (3EBC)_{16} ( 11 1110 1011 1100 ) 2 = ( 3 E B C ) 16 。
反过来手续相同。二进制与十六进制互转时,若位数不是 4 4 4 的倍数,用 0 0 0 补齐。
进制转换本质上就是刚刚学过的除法与模运算。一般转换算法可以写成下面这个反复取余的版本,其中 n n n 是待转换的数,b b b 是目标底数。
算法 3 反复除法求进制展开
Require: 非负整数 n n n 与底数 b > 1 b>1 b > 1
Ensure: 数字 a k − 1 , … , a 0 a_{k-1},\ldots,a_0 a k − 1 , … , a 0 使得 n = ( a k − 1 … a 0 ) b n=(a_{k-1}\ldots a_0)_b n = ( a k − 1 … a 0 ) b
1: q ← n q \gets n q ← n
2: k ← 0 k \gets 0 k ← 0
3: while q > 0 q > 0 q > 0 do
4: a k ← q m o d b a_k \gets q \bmod b a k ← q mod b
5: q ← ⌊ q / b ⌋ q \gets \left\lfloor q / b \right\rfloor q ← ⌊ q / b ⌋
6: k ← k + 1 k \gets k+1 k ← k + 1
7: end while
8: return ( a k − 1 , … , a 1 , a 0 ) (a_{k-1},\ldots,a_1,a_0) ( a k − 1 , … , a 1 , a 0 )
运算算法
下面讨论二进制下基本运算的算法。把两个 n n n 位二进制整数写成
a = ( a n − 1 a n − 2 … a 1 a 0 ) 2 , b = ( b n − 1 b n − 2 … b 1 b 0 ) 2 . a=(a_{n-1}a_{n-2}\ldots a_1a_0)_2,\qquad b=(b_{n-1}b_{n-2}\ldots b_1b_0)_2. a = ( a n − 1 a n − 2 … a 1 a 0 ) 2 , b = ( b n − 1 b n − 2 … b 1 b 0 ) 2 .
加法算法
二进制加法可以模仿竖式:对应位与进位一起加。先加最右两位:
a 0 + b 0 = c 0 ⋅ 2 + s 0 , a_0 + b_0 = c_0 \cdot 2 + s_0, a 0 + b 0 = c 0 ⋅ 2 + s 0 ,
其中 s 0 s_0 s 0 是和的最右一位,c 0 c_0 c 0 是进位,取值 0 0 0 或 1 1 1 。再加下一位和进位:
a 1 + b 1 + c 0 = c 1 ⋅ 2 + s 1 . a_1 + b_1 + c_0 = c_1 \cdot 2 + s_1. a 1 + b 1 + c 0 = c 1 ⋅ 2 + s 1 .
如此直到最后,a n − 1 + b n − 1 + c n − 2 a_{n-1}+b_{n-1}+c_{n-2} a n − 1 + b n − 1 + c n − 2 给出 c n − 1 ⋅ 2 + s n − 1 c_{n-1}\cdot 2+s_{n-1} c n − 1 ⋅ 2 + s n − 1 ,和的最高位是 s n = c n − 1 s_n=c_{n-1} s n = c n − 1 。于是 a + b = ( s n s n − 1 … s 1 s 0 ) 2 a+b=(s_n s_{n-1}\ldots s_1 s_0)_2 a + b = ( s n s n − 1 … s 1 s 0 ) 2 。以 1011 2 1011_2 101 1 2 加 1101 2 1101_2 110 1 2 为例,竖式为
1011 2 + 1101 2 11000 2 \begin{array}{r}
1011_2 \\
+\,1101_2 \\
\hline
11000_2
\end{array} 101 1 2 + 110 1 2 1100 0 2
逐步如下。
最右位:1 + 1 = 10 2 1+1=10_2 1 + 1 = 1 0 2 ,写下 0 0 0 ,进位 1 1 1 。
下一位:1 + 0 + 1 = 10 2 1+0+1=10_2 1 + 0 + 1 = 1 0 2 ,写下 0 0 0 ,进位 1 1 1 。
再下一位:0 + 1 + 1 = 10 2 0+1+1=10_2 0 + 1 + 1 = 1 0 2 ,写下 0 0 0 ,进位 1 1 1 。
最高位:1 + 1 + 1 = 11 2 1+1+1=11_2 1 + 1 + 1 = 1 1 2 ,写下 1 1 1 ,再向左进位 1 1 1 。
把最后的进位写下。
结果是 11000 2 11000_2 1100 0 2 。
伪代码如下。
算法 4 二进制加法
Require: n n n 位整数 a a a 与 b b b
Ensure: a + b a+b a + b 的二进制展开
1: c ← 0 c \gets 0 c ← 0
2: for j ← 0 j \gets 0 j ← 0 to n − 1 n-1 n − 1 do
3: d ← ⌊ ( a j + b j + c ) / 2 ⌋ d \gets \left\lfloor (a_j+b_j+c)/2 \right\rfloor d ← ⌊ ( a j + b j + c ) /2 ⌋
4: s j ← a j + b j + c − 2 d s_j \gets a_j+b_j+c-2d s j ← a j + b j + c − 2 d
5: c ← d c \gets d c ← d
6: end for
7: s n ← c s_n \gets c s n ← c
8: return ( s n s n − 1 … s 1 s 0 ) 2 (s_ns_{n-1}\ldots s_1s_0)_2 ( s n s n − 1 … s 1 s 0 ) 2
时间复杂度 为 O ( n ) O(n) O ( n ) ,其中 n n n 是输入的二进制位数。
证明
算法只有一层循环,迭代 n n n 次,n n n 是两个加数的位数。循环体内对每一位做常数次运算:把第 j j j 位 a j + b j a_j+b_j a j + b j 与进位 c c c 相加,除以 2 2 2 得到新进位 d d d ,再减去 2 d 2d 2 d 得到和的第 j j j 位,最后把 c c c 更新为 d d d 。这些运算都是常数时间,每位执行一次,故整段循环对位数线性,总复杂度 O ( n ) O(n) O ( n ) 。这里假定基本算术(加、除以 2 2 2 、减)都是常数时间。
乘法算法
沿用同样的二进制写法,乘法是
a b = a ( b 0 2 0 + b 1 2 1 + ⋯ + b n − 1 2 n − 1 ) = a ( b 0 2 0 ) + a ( b 1 2 1 ) + ⋯ + a ( b n − 1 2 n − 1 ) . \begin{aligned}
a b & =a\left(b_{0} 2^{0}+b_{1} 2^{1}+\cdots+b_{n-1} 2^{n-1}\right) \\
& =a\left(b_{0} 2^{0}\right)+a\left(b_{1} 2^{1}\right)+\cdots+a\left(b_{n-1} 2^{n-1}\right).
\end{aligned} ab = a ( b 0 2 0 + b 1 2 1 + ⋯ + b n − 1 2 n − 1 ) = a ( b 0 2 0 ) + a ( b 1 2 1 ) + ⋯ + a ( b n − 1 2 n − 1 ) .
手续类似竖式:用第二个数的每一位去乘第一个数,再按位次左移后相加。
算法 5 二进制乘法
Require: n n n 位整数 a a a 与 b b b
Ensure: 乘积 a b ab ab
1: product ← 0 \text{product} \gets 0 product ← 0
2: for j ← 0 j \gets 0 j ← 0 to n − 1 n-1 n − 1 do
3: if b j = 1 b_j = 1 b j = 1 then
4: product ← product + a ⋅ 2 j \text{product} \gets \text{product} + a\cdot 2^j product ← product + a ⋅ 2 j
5: end if
6: end for
7: return product \text{product} product
例 ( 110 ) 2 (110)_2 ( 110 ) 2 乘 ( 101 ) 2 (101)_2 ( 101 ) 2 求 a = ( 110 ) 2 a = (110)_2 a = ( 110 ) 2 与 b = ( 101 ) 2 b = (101)_2 b = ( 101 ) 2 的乘积。先算
a ⋅ b 0 ⋅ 2 0 = ( 110 ) 2 ⋅ 1 ⋅ 2 0 = ( 110 ) 2 , a ⋅ b 1 ⋅ 2 1 = ( 110 ) 2 ⋅ 0 ⋅ 2 1 = ( 0000 ) 2 , a ⋅ b 2 ⋅ 2 2 = ( 110 ) 2 ⋅ 1 ⋅ 2 2 = ( 11000 ) 2 . \begin{aligned}
a \cdot b_0 \cdot 2^0 &= (110)_2 \cdot 1 \cdot 2^0 = (110)_2, \\
a \cdot b_1 \cdot 2^1 &= (110)_2 \cdot 0 \cdot 2^1 = (0000)_2, \\
a \cdot b_2 \cdot 2^2 &= (110)_2 \cdot 1 \cdot 2^2 = (11000)_2.
\end{aligned} a ⋅ b 0 ⋅ 2 0 a ⋅ b 1 ⋅ 2 1 a ⋅ b 2 ⋅ 2 2 = ( 110 ) 2 ⋅ 1 ⋅ 2 0 = ( 110 ) 2 , = ( 110 ) 2 ⋅ 0 ⋅ 2 1 = ( 0000 ) 2 , = ( 110 ) 2 ⋅ 1 ⋅ 2 2 = ( 11000 ) 2 . 把 ( 110 ) 2 (110)_2 ( 110 ) 2 、( 0000 ) 2 (0000)_2 ( 0000 ) 2 、( 11000 ) 2 (11000)_2 ( 11000 ) 2 相加(位数不够时在前面补零),得到 a b = ( 11110 ) 2 ab=(11110)_2 ab = ( 11110 ) 2 。
时间复杂度 为 O ( n 2 ) O(n^2) O ( n 2 ) :n n n 位与 n n n 位相乘,每一位都要和另一数的每一位打交道,共 n n n 组、每组 n n n 次。
商与余数算法
下面的算法求 a ÷ b a\div b a ÷ b 的商和余数,也能处理 a a a 为负的情形。
算法 6 带余除法
Require: 整数 a a a 与正整数 b b b
Ensure: 整数 ( q , r ) (q,r) ( q , r ) 使得 a = b q + r a=bq+r a = b q + r 且 0 ≤ r < b 0\le r<b 0 ≤ r < b
1: q ← ⌊ a / b ⌋ q \gets \left\lfloor a/b \right\rfloor q ← ⌊ a / b ⌋
2: r ← a − b q r \gets a-bq r ← a − b q
3: return ( q , r ) (q,r) ( q , r )
模幂算法
模运算的一个重要应用是高效计算 b n m o d m b^n \bmod m b n mod m ,密码学里经常需要。直接算 b n b^n b n 可能大到不可接受,所以要用快速方法。把指数写成二进制 n = ( a k − 1 … a 1 a 0 ) 2 n=(a_{k-1}\ldots a_1a_0)_2 n = ( a k − 1 … a 1 a 0 ) 2 ,则
b n = b a k − 1 ⋅ 2 k − 1 + ⋯ + a 1 ⋅ 2 + a 0 = b a k − 1 ⋅ 2 k − 1 ⋯ b a 1 ⋅ 2 ⋅ b a 0 . b^n=b^{a_{k-1}\cdot2^{k-1}+\cdots+a_1\cdot2+a_0}=b^{a_{k-1}\cdot2^{k-1}}\cdots b^{a_1\cdot2}\cdot b^{a_0}. b n = b a k − 1 ⋅ 2 k − 1 + ⋯ + a 1 ⋅ 2 + a 0 = b a k − 1 ⋅ 2 k − 1 ⋯ b a 1 ⋅ 2 ⋅ b a 0 .
因此只需依次算出 b b b 、b 2 b^2 b 2 、( b 2 ) 2 = b 4 (b^2)^2=b^4 ( b 2 ) 2 = b 4 、( b 4 ) 2 = b 8 (b^4)^2=b^8 ( b 4 ) 2 = b 8 、… \ldots … 、b 2 k b^{2^k} b 2 k ,再把 a j = 1 a_j=1 a j = 1 的那些 b 2 j b^{2^j} b 2 j 乘起来。为了省时间和空间,每乘一次就模 m m m 一次。
计算 4 9 4^9 4 9 。注意 9 = ( 1001 ) 2 9=(1001)_2 9 = ( 1001 ) 2 ,故 4 9 = 4 8 ⋅ 4 1 4^9=4^8\cdot 4^1 4 9 = 4 8 ⋅ 4 1 。连续平方:4 2 = 16 4^2=16 4 2 = 16 ,4 4 = 16 2 = 256 4^4=16^2=256 4 4 = 1 6 2 = 256 ,4 8 = ( 256 ) 2 = 65536 4^8=(256)^2=65536 4 8 = ( 256 ) 2 = 65536 。于是 4 9 = 4 8 ⋅ 4 1 = 65536 ⋅ 4 = 262144 4^9=4^8\cdot 4^1=65536\cdot 4=262144 4 9 = 4 8 ⋅ 4 1 = 65536 ⋅ 4 = 262144 。
有了求 b n b^n b n 的骨架,就可以写求 b n m o d m b^n\bmod m b n mod m 的算法。
算法 7 快速模幂
Require: 整数 b , n , m b,n,m b , n , m ,其中 n ≥ 0 n\ge 0 n ≥ 0 、m > 0 m>0 m > 0
Ensure: b n m o d m b^n \bmod m b n mod m
1: x ← 1 x \gets 1 x ← 1
2: power ← b m o d m \text{power} \gets b \bmod m power ← b mod m
3: exponent ← n \text{exponent} \gets n exponent ← n
4: while exponent > 0 \text{exponent} > 0 exponent > 0 do
5: if exponent m o d 2 = 1 \text{exponent} \bmod 2 = 1 exponent mod 2 = 1 then
6: x ← ( x ⋅ power ) m o d m x \gets (x\cdot \text{power}) \bmod m x ← ( x ⋅ power ) mod m
7: end if
8: power ← ( power ⋅ power ) m o d m \text{power} \gets (\text{power}\cdot \text{power}) \bmod m power ← ( power ⋅ power ) mod m
9: exponent ← ⌊ exponent / 2 ⌋ \text{exponent} \gets \left\lfloor \text{exponent}/2 \right\rfloor exponent ← ⌊ exponent /2 ⌋
10: end while
11: return x x x
例 用算法求 3 644 m o d 645 3^{644}\bmod 645 3 644 mod 645 用上述算法求 3 644 m o d 645 3^{644} \bmod 645 3 644 mod 645 。
算法先令 x = 1 x=1 x = 1 、p o w e r = 3 m o d 645 = 3 power=3\bmod 645=3 p o w er = 3 mod 645 = 3 ,再反复平方并模 645 645 645 ,得到 3 2 j m o d 645 3^{2^j}\bmod 645 3 2 j mod 645 (j = 1 , 2 , … , 9 j=1,2,\ldots,9 j = 1 , 2 , … , 9 )。当 644 644 644 的二进制 ( 1010000100 ) 2 (1010000100)_2 ( 1010000100 ) 2 的第 j j j 位为 1 1 1 时,把当前 x x x 乘上 3 2 j m o d 645 3^{2^j}\bmod 645 3 2 j mod 645 再模 645 645 645 。逐步如下。
步 计算 i = 0 i = 0 i = 0 a 0 = 0 a_0 = 0 a 0 = 0 ,故 x = 1 x = 1 x = 1 ,p o w e r = 3 2 m o d 645 = 9 power = 3^2 \bmod 645 = 9 p o w er = 3 2 mod 645 = 9 i = 1 i = 1 i = 1 a 1 = 0 a_1 = 0 a 1 = 0 ,故 x = 1 x = 1 x = 1 ,p o w e r = 9 2 m o d 645 = 81 power = 9^2 \bmod 645 = 81 p o w er = 9 2 mod 645 = 81 i = 2 i = 2 i = 2 a 2 = 1 a_2 = 1 a 2 = 1 ,故 x = 1 ⋅ 81 m o d 645 = 81 x = 1 \cdot 81 \bmod 645 = 81 x = 1 ⋅ 81 mod 645 = 81 ,p o w e r = 81 2 m o d 645 = 111 power = 81^2 \bmod 645 = 111 p o w er = 8 1 2 mod 645 = 111 i = 3 i = 3 i = 3 a 3 = 0 a_3 = 0 a 3 = 0 ,故 x = 81 x = 81 x = 81 ,p o w e r = 111 2 m o d 645 = 66 power = 111^2 \bmod 645 = 66 p o w er = 11 1 2 mod 645 = 66 i = 4 i = 4 i = 4 a 4 = 0 a_4 = 0 a 4 = 0 ,故 x = 81 x = 81 x = 81 ,p o w e r = 66 2 m o d 645 = 486 power = 66^2 \bmod 645 = 486 p o w er = 6 6 2 mod 645 = 486 i = 5 i = 5 i = 5 a 5 = 0 a_5 = 0 a 5 = 0 ,故 x = 81 x = 81 x = 81 ,p o w e r = 486 2 m o d 645 = 126 power = 486^2 \bmod 645 = 126 p o w er = 48 6 2 mod 645 = 126 i = 6 i = 6 i = 6 a 6 = 0 a_6 = 0 a 6 = 0 ,故 x = 81 x = 81 x = 81 ,p o w e r = 126 2 m o d 645 = 396 power = 126^2 \bmod 645 = 396 p o w er = 12 6 2 mod 645 = 396 i = 7 i = 7 i = 7 a 7 = 1 a_7 = 1 a 7 = 1 ,故 x = ( 81 ⋅ 396 ) m o d 645 = 471 x = (81 \cdot 396) \bmod 645 = 471 x = ( 81 ⋅ 396 ) mod 645 = 471 ,p o w e r = 396 2 m o d 645 = 81 power = 396^2 \bmod 645 = 81 p o w er = 39 6 2 mod 645 = 81 i = 8 i = 8 i = 8 a 8 = 0 a_8 = 0 a 8 = 0 ,故 x = 471 x = 471 x = 471 ,p o w e r = 81 2 m o d 645 = 111 power = 81^2 \bmod 645 = 111 p o w er = 8 1 2 mod 645 = 111 i = 9 i = 9 i = 9 a 9 = 1 a_9 = 1 a 9 = 1 ,故 x = ( 471 ⋅ 111 ) m o d 645 = 36 x = (471 \cdot 111) \bmod 645 = 36 x = ( 471 ⋅ 111 ) mod 645 = 36
因此 3 644 m o d 645 = 36 3^{644} \bmod 645 = 36 3 644 mod 645 = 36 。
模幂算法的时间复杂度
循环次数等于指数 n n n 的二进制位数。每轮做常数次模乘和模平方,故复杂度为 O ( log n ) O(\log n) O ( log n ) 。朴素模幂是 O ( n ) O(n) O ( n ) ,对数级改进在 RSA 这类指数很大的密码算法里至关重要。
证明
设指数为 n n n ,其二进制位数为 k k k ,即
n = ∑ i = 0 k − 1 a i ⋅ 2 i , a i ∈ { 0 , 1 } . n = \sum_{i=0}^{k-1} a_i \cdot 2^i,\qquad a_i \in \{0, 1\}. n = i = 0 ∑ k − 1 a i ⋅ 2 i , a i ∈ { 0 , 1 } . 算法从低位到高位扫描这些比特。每轮:若 a i = 1 a_i=1 a i = 1 ,就做一次模乘更新 x x x ;无论 a i a_i a i 是什么,都做一次模平方更新 p o w e r power p o w er 。模乘和模平方用模 m m m 的常数次算术即可完成,视为 O ( 1 ) O(1) O ( 1 ) 。总共 k k k 轮,故时间与 k k k 成正比。而 k = ⌊ log 2 n ⌋ + 1 = O ( log n ) k=\lfloor\log_2 n\rfloor+1=O(\log n) k = ⌊ log 2 n ⌋ + 1 = O ( log n ) ,因此算法复杂度为 O ( log n ) O(\log n) O ( log n ) 。
对数时间的快速模幂,比线性时间的朴素反复相乘高效得多。
素数与最大公因数
前面讲了整除、余数和模运算,这是数论最基础的一层。现在转向素数及其性质。素数并不陌生,幼儿园或小学就见过。下面讨论如何判定素数、如何分解,并进入素数的代数性质。这些都是密码学的地基。
素数及相关算法
先把定义写清楚。
定义 素数
大于 1 1 1 的整数 p p p ,若其仅有的正因数是 1 1 1 和 p p p ,则称为素数。大于 1 1 1 且不是素数的正整数称为合数 。
按这个定义,1 1 1 不是素数:它只有正因数 1 1 1 。
素数令人着迷,是因为它有许多独特的性质,远不止定义本身。其中最核心的是算术基本定理。
定理 算术基本定理
每个整数 n > 1 n>1 n > 1 都可以唯一地分解成素数的乘积,不计因子次序。具体地,n n n 可以写成
n = p 1 a 1 ⋅ p 2 a 2 ⋅ … ⋅ p k a k , n = p_1^{a_1} \cdot p_2^{a_2} \cdot \ldots \cdot p_k^{a_k}, n = p 1 a 1 ⋅ p 2 a 2 ⋅ … ⋅ p k a k , 其中 p 1 < p 2 < … < p k p_1 < p_2 < \ldots < p_k p 1 < p 2 < … < p k 是素数,a 1 , a 2 , … , a k a_1, a_2, \ldots, a_k a 1 , a 2 , … , a k 是正整数。除次序外,这个分解唯一。
证明
分存在性和唯一性两部分。
存在性。 用数学归纳法证明每个大于 1 1 1 的整数都能写成素数之积。
基础:n = 2 n=2 n = 2 本身是素数。
归纳:假设命题对一切大于 1 1 1 且小于 n n n 的整数成立,考虑 n n n 。若 n n n 是素数,则它已经是素数之积。若 n n n 不是素数,则可写成 n = a ⋅ b n=a\cdot b n = a ⋅ b ,其中 1 < a , b < n 1<a,b<n 1 < a , b < n 。由归纳假设,a a a 与 b b b 都能分解成素数之积,合在一起就得到 n n n 的分解。存在性证完。
唯一性。 反设 n n n 有两种不同的素因子分解:
n = p 1 a 1 ⋅ p 2 a 2 ⋅ … ⋅ p k a k = q 1 b 1 ⋅ q 2 b 2 ⋅ … ⋅ q m b m , n = p_1^{a_1} \cdot p_2^{a_2} \cdot \ldots \cdot p_k^{a_k} = q_1^{b_1} \cdot q_2^{b_2} \cdot \ldots \cdot q_m^{b_m}, n = p 1 a 1 ⋅ p 2 a 2 ⋅ … ⋅ p k a k = q 1 b 1 ⋅ q 2 b 2 ⋅ … ⋅ q m b m , 其中 p i p_i p i 、q j q_j q j 为素数,a i a_i a i 、b j b_j b j 为正整数。接下来需要欧几里得引理。
引理(欧几里得)。 设 p p p 为素数。若 p p p 整除乘积 a b ab ab ,则 p p p 整除 a a a 或 p p p 整除 b b b 。
引理的证明。 设素数 p p p 整除 a b ab ab 但不整除 a a a ,要证 p p p 整除 b b b 。由于 p p p 不整除 a a a ,gcd ( a , p ) = 1 \gcd(a,p)=1 g cd( a , p ) = 1 。由贝祖恒等式,存在整数 x x x 、y y y 使得
a x + p y = 1. ax + py = 1. a x + p y = 1. 两边乘 b b b :
a b x + p b y = b . abx + pby = b. ab x + p b y = b . (若这一步暂时读不顺,可先看完线性组合与贝祖定理再回来。)
p p p 整除 a b ab ab ,故整除 a b x abx ab x ;显然也整除 p b y pby p b y 。于是 p p p 整除二者之和,即整除 b b b 。这就证明了:若 p p p 整除 a b ab ab 且不整除 a a a ,则 p p p 整除 b b b 。
回到唯一性。由欧几里得引理,素数若整除两个数的积,必整除其中至少一个。因此 p 1 p_1 p 1 必须整除右端某个 q j q_j q j 。但 q j q_j q j 是素数,故 p 1 = q j p_1=q_j p 1 = q j 。对称地反复使用这一论证,两套素因子必须完全相同,与“两种不同分解”矛盾。
因此大于 1 1 1 的整数的素因子分解在不计次序时唯一。
100 = 2 ⋅ 2 ⋅ 5 ⋅ 5 = 2 2 ⋅ 5 2 100 = 2\cdot 2\cdot 5\cdot 5 = 2^2\cdot 5^2 100 = 2 ⋅ 2 ⋅ 5 ⋅ 5 = 2 2 ⋅ 5 2 ,其中 2 2 2 和 5 5 5 都是素数。
知道素数重要之后,怎样又对又快地找出它们?最朴素的办法是逐个试:要判断 n n n 是不是素数,从 2 2 2 除到 n − 1 n-1 n − 1 ,谁整除 n n n ,n n n 就不是素数。
试除法
其实不必除到 n − 1 n-1 n − 1 。下面这条定理把上界降到平方根。
定理 试除上界
若 n n n 是合数,则 n n n 有一个不超过 n \sqrt{n} n 的素因数。
证明
n n n 是合数,故有因数 a a a 满足 1 < a < n 1<a<n 1 < a < n ,从而 n = a b n=ab n = ab ,其中 b > 1 b>1 b > 1 。下面说明 a ≤ n a\le\sqrt{n} a ≤ n 或 b ≤ n b\le\sqrt{n} b ≤ n 。若二者都大于 n \sqrt{n} n ,则 a b > n ⋅ n = n ab>\sqrt{n}\cdot\sqrt{n}=n ab > n ⋅ n = n ,矛盾。故 n n n 有一个不超过 n \sqrt{n} n 的正因数。这个因数要么本身是素数,要么(由算术基本定理)有更小的素因数。无论哪种,n n n 都有不超过 n \sqrt{n} n 的素因数。
判定手续的伪代码如下。
算法 8 试除素性判定
Require: 整数 n > 1 n>1 n > 1
Ensure: n n n 是否为素数
1: if n = 2 n=2 n = 2 then
3: end if
4: d ← 2 d \gets 2 d ← 2
5: while d ≤ n d \le \sqrt n d ≤ n do
6: if n m o d d = 0 n \bmod d = 0 n mod d = 0 then
8: end if
9: d ← d + 1 d \gets d+1 d ← d + 1
10: end while
11: return true
不超过 101 \sqrt{101} 101 的素数是 2 2 2 、3 3 3 、5 5 5 、7 7 7 。101 101 101 不被它们任何一个整除,因此不是合数,也就是素数。
还需要把给定整数分解成素因子。试除分解如下。
算法 9 试除素因子分解
Require: 整数 n > 1 n>1 n > 1
Ensure: n n n 的素因子
1: factors ← \text{factors} \gets factors ← 空列表
2: p ← 2 p \gets 2 p ← 2
3: while p 2 ≤ n p^2 \le n p 2 ≤ n do
4: while n m o d p = 0 n \bmod p = 0 n mod p = 0 do
5: 把 p p p 追加到 factors \text{factors} factors
6: n ← n / p n \gets n/p n ← n / p
7: end while
8: p ← p + 1 p \gets p+1 p ← p + 1
9: end while
10: if n > 1 n>1 n > 1 then
11: 把 n n n 追加到 factors \text{factors} factors
12: end if
13: return factors \text{factors} factors
8964 8964 8964 是偶数,先除以 2 2 2 :8964 ÷ 2 = 4482 8964\div 2=4482 8964 ÷ 2 = 4482 。
4482 4482 4482 仍是偶数:4482 ÷ 2 = 2241 4482\div 2=2241 4482 ÷ 2 = 2241 。
2241 2241 2241 不能被 2 2 2 整除。依次试 3 3 3 、5 5 5 、7 7 7 、11 11 11 等,直到 31 31 31 。
2241 ÷ 31 = 71 2241\div 31=71 2241 ÷ 31 = 71 ,而 71 71 71 是素数。
因此 8964 = 2 × 2 × 31 × 71 8964=2\times 2\times 31\times 71 8964 = 2 × 2 × 31 × 71 ,或写成 2 2 × 31 × 71 2^2\times 31\times 71 2 2 × 31 × 71 。
还有其他找素数或判定素性的方法。愿意深挖的话可以看 埃拉托斯特尼筛 和 阿特金筛 。这只是一小部分;后面解同余时会遇到费马小定理,概率论里还会遇到蒙特卡洛方法。
最大公因数与最小公倍数
再回到小学就见过的最大公因数和最小公倍数。先写定义。
定义 最大公因数
设 a a a 、b b b 为不全为零的整数。同时整除 a a a 和 b b b 的最大整数 d d d 称为它们的最大公因数,记作 gcd ( a , b ) \gcd(a,b) g cd( a , b ) 。
例 计算两个 gcd
求 gcd ( 12 , 24 ) \gcd(12,24) g cd( 12 , 24 ) 和 gcd ( 17 , 22 ) \gcd(17,22) g cd( 17 , 22 ) 。
能同时整除 12 12 12 和 24 24 24 的最大正整数是 6 6 6 ,故 gcd ( 12 , 24 ) = 6 \gcd(12,24)=6 g cd( 12 , 24 ) = 6 。17 17 17 与 22 22 22 除 1 1 1 外没有公因数,故 gcd ( 17 , 22 ) = 1 \gcd(17,22)=1 g cd( 17 , 22 ) = 1 。
gcd ( 17 , 22 ) = 1 \gcd(17,22)=1 g cd( 17 , 22 ) = 1 时,称这两个数互质 。
可以把互质推广到两两互质。
定义 两两互质
整数 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a 1 , a 2 , … , a n 称为两两互质,如果每当 1 ≤ i < j ≤ n 1\le i<j\le n 1 ≤ i < j ≤ n 时都有 gcd ( a i , a j ) = 1 \gcd(a_i,a_j)=1 g cd( a i , a j ) = 1 。
例如 9 9 9 、16 16 16 、23 23 23 两两互质,因为 gcd ( 9 , 16 ) = gcd ( 9 , 23 ) = gcd ( 16 , 23 ) = 1 \gcd(9,16)=\gcd(9,23)=\gcd(16,23)=1 g cd( 9 , 16 ) = g cd( 9 , 23 ) = g cd( 16 , 23 ) = 1 。一列整数两两互质,当且仅当任意两个不同项的最大公因数都是 1 1 1 。
也可以用素因子分解求 gcd。设正整数 a a a 、b b b 的素因子分解为
a = p 1 a 1 p 2 a 2 ⋯ p n a n , b = p 1 b 1 p 2 b 2 ⋯ p n b n , a=p_1^{a_1}p_2^{a_2}\cdots p_n^{a_n},\qquad b=p_1^{b_1}p_2^{b_2}\cdots p_n^{b_n}, a = p 1 a 1 p 2 a 2 ⋯ p n a n , b = p 1 b 1 p 2 b 2 ⋯ p n b n ,
其中指数是非负整数;某个素数若只出现在一边,另一边指数取 0 0 0 。则
gcd ( a , b ) = p 1 min ( a 1 , b 1 ) p 2 min ( a 2 , b 2 ) ⋯ p n min ( a n , b n ) , \gcd(a,b)=p_1^{\min(a_1,b_1)}p_2^{\min(a_2,b_2)}\cdots p_n^{\min(a_n,b_n)}, g cd( a , b ) = p 1 m i n ( a 1 , b 1 ) p 2 m i n ( a 2 , b 2 ) ⋯ p n m i n ( a n , b n ) ,
其中 min ( x , y ) \min(x,y) min ( x , y ) 表示 x x x 与 y y y 中较小的那个。右边这个整数整除 a a a 也整除 b b b ,因为每个素数的指数都不超过 a a a 、b b b 两边的指数;再增大任何一个指数,或加入新的素数,就会不再同时整除两边。因此它就是最大公因数。
例 用分解求 gcd ( 100 , 250 ) \gcd(100,250) g cd( 100 , 250 ) gcd ( 100 , 250 ) = 2 min ( 2 , 1 ) 5 min ( 2 , 3 ) = 2 ⋅ 5 2 = 50. \gcd(100,250)=2^{\min(2,1)}5^{\min(2,3)}=2\cdot5^2=50. g cd( 100 , 250 ) = 2 m i n ( 2 , 1 ) 5 m i n ( 2 , 3 ) = 2 ⋅ 5 2 = 50.
同一套素因子方法给出最小公倍数。算术基本定理保证每个大于 1 1 1 的整数都有唯一的素因子分解。
定义 最小公倍数
正整数 a a a 、b b b 的最小公倍数是同时被 a a a 和 b b b 整除的最小正整数,记作 lcm ( a , b ) \operatorname{lcm}(a,b) lcm ( a , b ) 。
仍设
a = p 1 a 1 p 2 a 2 … p n a n , b = p 1 b 1 p 2 b 2 … p n b n . a = p_1^{a_1} p_2^{a_2} \ldots p_n^{a_n},\qquad b = p_1^{b_1} p_2^{b_2} \ldots p_n^{b_n}. a = p 1 a 1 p 2 a 2 … p n a n , b = p 1 b 1 p 2 b 2 … p n b n .
乘积 a b ab ab 的素因子分解是
a b = p 1 a 1 + b 1 p 2 a 2 + b 2 … p n a n + b n . ab = p_1^{a_1+b_1} p_2^{a_2+b_2} \ldots p_n^{a_n+b_n}. ab = p 1 a 1 + b 1 p 2 a 2 + b 2 … p n a n + b n .
任何公倍数在每个素数上的指数,都必须至少达到 a a a 、b b b 两边的较大者。因此
lcm ( a , b ) = p 1 max ( a 1 , b 1 ) p 2 max ( a 2 , b 2 ) … p n max ( a n , b n ) . \operatorname{lcm}(a, b) = p_1^{\max(a_1,b_1)} p_2^{\max(a_2,b_2)} \ldots p_n^{\max(a_n,b_n)}. lcm ( a , b ) = p 1 m a x ( a 1 , b 1 ) p 2 m a x ( a 2 , b 2 ) … p n m a x ( a n , b n ) .
它被 a a a 和 b b b 整除,而且是满足这一性质的最小正整数。
例 求 lcm ( 120 , 500 ) \operatorname{lcm}(120,500) lcm ( 120 , 500 ) lcm ( 120 , 500 ) = 2 max ( 2 , 3 ) 3 max ( 1 , 0 ) 5 max ( 1 , 3 ) = 8 × 3 × 125 = 3000. \operatorname{lcm}(120,500)=2^{\max(2,3)}3^{\max(1,0)}5^{\max(1,3)} = 8\times 3 \times 125= 3000. lcm ( 120 , 500 ) = 2 m a x ( 2 , 3 ) 3 m a x ( 1 , 0 ) 5 m a x ( 1 , 3 ) = 8 × 3 × 125 = 3000.
注意到 a b ab ab 恰好等于 lcm ( a , b ) \operatorname{lcm}(a,b) lcm ( a , b ) 与 gcd ( a , b ) \gcd(a,b) g cd( a , b ) 的乘积:在 a b ab ab 的分解里每个指数都是两边指数之和,无论谁大谁小,都有 max + min = \max+\min= max + min = 两边之和。对 120 120 120 和 500 500 500 ,
a b = 120 × 500 = 60000 = lcm ( a , b ) × gcd ( a , b ) = 3000 × 20. ab = 120\times 500 = 60000 = \operatorname{lcm}(a,b)\times \gcd(a,b) = 3000\times 20. ab = 120 × 500 = 60000 = lcm ( a , b ) × g cd( a , b ) = 3000 × 20.
定理 gcd 与 lcm 的乘积恒等式
设 a a a 、b b b 为正整数。则 a b = gcd ( a , b ) ⋅ lcm ( a , b ) ab= \gcd(a, b)\cdot\operatorname{lcm}(a, b) ab = g cd( a , b ) ⋅ lcm ( a , b ) 。
证明
对每个素数 p p p ,设它在 a , b a,b a , b 中的指数为 u , v u,v u , v ,允许为零。gcd 中的指数为 min ( u , v ) \min(u,v) min ( u , v ) ,lcm 中为 max ( u , v ) \max(u,v) max ( u , v ) ,两者之和为 u + v u+v u + v ,恰为 a b ab ab 中的指数。唯一素因子分解便证明乘积相等。
欧几里得算法
对整数 a ≥ b > 0 a\ge b>0 a ≥ b > 0 ,写 a = q b + r a=qb+r a = q b + r ,其中 0 ≤ r < b 0\le r<b 0 ≤ r < b 。正整数同时整除 a , b a,b a , b ,当且仅当同时整除 b , r b,r b , r :一个方向用 r = a − q b r=a-qb r = a − q b ,另一个方向用 a = q b + r a=qb+r a = q b + r 。因此
gcd ( a , b ) = gcd ( b , r ) . \gcd(a,b)=\gcd(b,r). g cd( a , b ) = g cd( b , r ) .
反复更新 ( a , b ) ← ( b , r ) (a,b)\leftarrow(b,r) ( a , b ) ← ( b , r ) 。只要还需下一次除法,非负余数就严格减小,故必终止。最后一对为 ( d , 0 ) (d,0) ( d , 0 ) ,其 gcd 是 d d d ;不变量保证这也是原来的 gcd。带符号输入先取绝对值,一项为零时直接返回另一项的绝对值。逐层反代这些除法等式,就把 d d d 写成原始输入的整数线性组合,得到下一节的贝祖恒等式。
每次取余都保持最大公因数不变,最后一个非零余数就是答案。
作为线性组合的最大公因数
两个整数 a a a 、b b b 的最大公因数可以写成
s a + t b , sa + tb, s a + t b ,
其中 s s s 、t t t 为整数。也就是说,gcd ( a , b ) \gcd(a,b) g cd( a , b ) 是 a a a 与 b b b 的整系数线性组合。这正是贝祖定理。
定理 贝祖恒等式
设 a a a 、b b b 为不全为零的整数。存在整数 x x x 、y y y 使得
a x + b y = gcd ( a , b ) . ax + by = \gcd(a, b). a x + b y = g cd( a , b ) . x x x 、y y y 叫做贝祖系数,等式 gcd ( a , b ) = s a + t b \gcd(a,b)=sa+tb g cd( a , b ) = s a + t b 叫做贝祖恒等式。
证明
对非零整数 a a a 、b b b ,用 b b b 除 a a a 得到余数 r 1 r_1 r 1 ,满足 0 ≤ r 1 < ∣ b ∣ 0\le r_1<|b| 0 ≤ r 1 < ∣ b ∣ ,且 gcd ( a , b ) = gcd ( b , r 1 ) \gcd(a,b)=\gcd(b,r_1) g cd( a , b ) = g cd( b , r 1 ) 。反复做带余除法:
a = b x 1 + r 1 , 0 < r 1 < ∣ b ∣ , b = r 1 x 2 + r 2 , 0 < r 2 < r 1 , ⋮ r n − 1 = r n x n + 1 + r n + 1 , 0 < r n + 1 < r n , r n = r n + 1 x n + 2 . \begin{aligned}
a&=bx_1+r_1,&& 0<r_1<|b|,\\
b&=r_1x_2+r_2,&& 0<r_2<r_1,\\
&\vdots\\
r_{n-1}&=r_n x_{n+1}+r_{n+1},&& 0<r_{n+1}<r_n,\\
r_n&=r_{n+1}x_{n+2}.
\end{aligned} a b r n − 1 r n = b x 1 + r 1 , = r 1 x 2 + r 2 , ⋮ = r n x n + 1 + r n + 1 , = r n + 1 x n + 2 . 0 < r 1 < ∣ b ∣ , 0 < r 2 < r 1 , 0 < r n + 1 < r n , r n + 1 r_{n+1} r n + 1 是最后一个非零余数。用倒数第二个等式把 r n + 1 r_{n+1} r n + 1 解成 r n r_n r n 与 r n − 1 r_{n-1} r n − 1 的组合,再往回代,依次消掉中间余数,最终把 r n + 1 r_{n+1} r n + 1 写成 a a a 与 b b b 的线性组合。而最后一个非零余数正是 gcd ( a , b ) \gcd(a,b) g cd( a , b ) ,这就是贝祖恒等式。更细的写法见 贝祖引理 。
欧几里得算法是递归的:求 gcd ( a , b ) \gcd(a,b) g cd( a , b ) 要多次调用同一手续。下面用例子把步骤写开。
例 用欧几里得算法求 gcd ( 1022 , 400 ) \gcd(1022,400) g cd( 1022 , 400 ) 用欧几里得算法求 1022 1022 1022 与 400 400 400 的最大公因数。
1022 = 2 × 400 + 222 , 400 = 1 × 222 + 178 , 222 = 1 × 178 + 44 , 178 = 4 × 44 + 2 , 44 = 22 × 2 + 0. \begin{aligned}
1022&=2\times400+222,\\
400&=1\times 222+178,\\
222&=1\times 178+44,\\
178&=4\times 44+2,\\
44&=22\times2+0.
\end{aligned} 1022 400 222 178 44 = 2 × 400 + 222 , = 1 × 222 + 178 , = 1 × 178 + 44 , = 4 × 44 + 2 , = 22 × 2 + 0.
于是 gcd ( 1022 , 400 ) = 2 \gcd(1022,400)=2 g cd( 1022 , 400 ) = 2 。把这些式子逐步反代,就是扩展欧几里得算法 。中间项都能用更前面的式子表示,最后得到 gcd 关于 1022 1022 1022 与 400 400 400 的线性组合:2 = 23 × 400 − 9 × 1022 2 = 23\times 400-9\times 1022 2 = 23 × 400 − 9 × 1022 。
换一种问法:求整数 a a a 、b b b 使得 gcd ( 1022 , 400 ) = a × 1022 + b × 400 \gcd(1022,400)=a\times 1022+b\times 400 g cd( 1022 , 400 ) = a × 1022 + b × 400 。手续完全一样,立刻得到 a = − 9 a=-9 a = − 9 、b = 23 b=23 b = 23 。下一节解线性同余时,还会看到与这等价的第三种写法。
解同余方程
本章从整除出发,定义了除法、模运算和同余,并看到同余的许多代数性质几乎是在“抄”普通算术。学实数时,运算熟了就开始用字母代替具体数字,那就是代数。同余既然共享这么多基本性质,能不能也做方程?本节只解线性同余,而欧几里得算法会再次成为主要工具。
线性同余
定义 线性同余
形如
a x ≡ b ( m o d m ) ax \equiv b \pmod{m} a x ≡ b ( mod m ) 的同余叫做线性同余 ,其中 a , b , m ∈ Z + a,b,m\in\mathbb{Z}^{+} a , b , m ∈ Z + ,x x x 是未知数。为了解它,需要找到 a ˉ \bar{a} a ˉ ,称为 a a a 模 m m m 的逆 ,满足 a a ˉ ≡ 1 ( m o d m ) a\bar{a}\equiv 1\pmod{m} a a ˉ ≡ 1 ( mod m ) 。
解会是什么样?同余有周期性,所以若有解,就会有无穷多个。
定理 模逆的存在与唯一性
若 a a a 与 m m m 互质且 m > 1 m>1 m > 1 ,则 a a a 模 m m m 的逆存在,并且在模 m m m 的意义下唯一。也就是说,存在唯一的正整数 a ˉ \bar{a} a ˉ 是 a a a 模 m m m 的逆,而其余的逆都与 a ˉ \bar{a} a ˉ 模 m m m 同余。
证明
由贝祖定理,gcd ( a , m ) = 1 \gcd(a,m)=1 g cd( a , m ) = 1 给出整数 s s s 、t t t 使得 s a + t m = 1 sa+tm=1 s a + t m = 1 。于是 s a + t m ≡ 1 ( m o d m ) sa+tm\equiv 1\pmod{m} s a + t m ≡ 1 ( mod m ) 。而 t m ≡ 0 ( m o d m ) tm\equiv 0\pmod{m} t m ≡ 0 ( mod m ) ,故 s a ≡ 1 ( m o d m ) sa\equiv 1\pmod{m} s a ≡ 1 ( mod m ) ,即 s s s 是 a a a 模 m m m 的一个逆。
再证唯一性。设另有 x x x 满足 x a ≡ 1 ( m o d m ) xa\equiv 1\pmod{m} x a ≡ 1 ( mod m ) ,且 x ≢ s ( m o d m ) x\not\equiv s\pmod{m} x ≡ s ( mod m ) 。则 x a ≡ s a ( m o d m ) xa\equiv sa\pmod{m} x a ≡ s a ( mod m ) ,故 m ∣ x a − s a m\mid xa-sa m ∣ x a − s a ,即 x − s x-s x − s 是 m m m 的倍数,从而 x ≡ s ( m o d m ) x\equiv s\pmod{m} x ≡ s ( mod m ) ,与假设矛盾。因此在模 m m m 下逆唯一。
例 求 101 101 101 模 5000 5000 5000 的一个逆 求 101 101 101 模 5000 5000 5000 的一个逆。
先用欧几里得算法说明 gcd ( 101 , 5000 ) = 1 \gcd(101,5000)=1 g cd( 101 , 5000 ) = 1 ,再反代求出贝祖系数 a a a 、b b b 使得 101 a + 5000 b = 1 101a+5000b=1 101 a + 5000 b = 1 ,则 a a a 就是所求的逆。欧几里得步骤为
5000 = 49 ⋅ 101 + 51 , 101 = 1 ⋅ 51 + 50 , 51 = 1 ⋅ 50 + 1 , 50 = 50 ⋅ 1. \begin{aligned}
5000 &= 49 \cdot 101 + 51, \\
101 &= 1 \cdot 51 + 50, \\
51 &= 1 \cdot 50 + 1, \\
50 &= 50 \cdot 1.
\end{aligned} 5000 101 51 50 = 49 ⋅ 101 + 51 , = 1 ⋅ 51 + 50 , = 1 ⋅ 50 + 1 , = 50 ⋅ 1.
最后一个非零余数是 1 1 1 ,故 gcd ( 101 , 5000 ) = 1 \gcd(101,5000)=1 g cd( 101 , 5000 ) = 1 。往回代:
1 = 51 − 1 ⋅ 50 = 51 − 1 ⋅ ( 101 − 1 ⋅ 51 ) = 2 ⋅ 51 − 101 = 2 ⋅ ( 5000 − 49 ⋅ 101 ) − 101 = 2 ⋅ 5000 − 99 ⋅ 101. \begin{aligned}
1 &= 51 - 1 \cdot 50 \\
&= 51 - 1 \cdot (101 - 1 \cdot 51) \\
&= 2 \cdot 51 - 101 \\
&= 2 \cdot (5000 - 49 \cdot 101) - 101 \\
&= 2 \cdot 5000 - 99 \cdot 101.
\end{aligned} 1 = 51 − 1 ⋅ 50 = 51 − 1 ⋅ ( 101 − 1 ⋅ 51 ) = 2 ⋅ 51 − 101 = 2 ⋅ ( 5000 − 49 ⋅ 101 ) − 101 = 2 ⋅ 5000 − 99 ⋅ 101.
由 − 99 ⋅ 101 + 2 ⋅ 5000 = 1 -99\cdot 101 + 2\cdot 5000 = 1 − 99 ⋅ 101 + 2 ⋅ 5000 = 1 可知 − 99 -99 − 99 是 101 101 101 模 5000 5000 5000 的一个逆。
例 解 101 x ≡ 3 ( m o d 5000 ) 101x\equiv 3\pmod{5000} 101 x ≡ 3 ( mod 5000 ) 线性同余 101 x ≡ 3 ( m o d 5000 ) 101x \equiv 3 \pmod {5000} 101 x ≡ 3 ( mod 5000 ) 的解是什么?
已知 − 99 -99 − 99 是 101 101 101 模 5000 5000 5000 的逆。两边同乘这个逆:
− 99 ⋅ 101 x ≡ − 99 ⋅ 3 ( m o d 5000 ) . -99 \cdot 101x \equiv -99\cdot 3 \pmod {5000}. − 99 ⋅ 101 x ≡ − 99 ⋅ 3 ( mod 5000 ) .
左边 ≡ x \equiv x ≡ x ,故 x ≡ − 99 ⋅ 3 ( m o d 5000 ) x\equiv -99\cdot 3 \pmod{5000} x ≡ − 99 ⋅ 3 ( mod 5000 ) 。解不是单个数,而是一整类:x = − 297 , − 5293 , 4703 , … x=-297,-5293,4703,\ldots x = − 297 , − 5293 , 4703 , … 。通解写成 x = x 0 + k m x=x_0+km x = x 0 + k m ,其中 k k k 为任意整数,x 0 x_0 x 0 是任何一个特解。
到此,只要同余可解(存在逆),线性同余都能解。前面一直假定 gcd ( a , m ) = 1 \gcd(a,m)=1 g cd( a , m ) = 1 。不互质时会怎样?
线性同余其实是更大一类方程的特例:丢番图方程 。
定义 丢番图方程
丢番图方程是要求未知数取整数的多项式方程或方程组,以亚历山大的丢番图命名。一般可以写成
a 1 x 1 b 1 + a 2 x 2 b 2 + ⋯ + a n x n b n = c , a_{1}x_{1}^{b_{1}}+a_{2}x_{2}^{b_{2}}+\cdots+a_{n}x_{n}^{b_{n}}=c, a 1 x 1 b 1 + a 2 x 2 b 2 + ⋯ + a n x n b n = c , 其中系数、指数、未知数和右端都在整数里。
一般的丢番图方程很难,解往往无穷多。最简单的线性情形是
a x + b y = c . ax+by=c. a x + b y = c .
这正是贝祖定理里出现的形状。求一对整数与它们 gcd 的线性关系,和解线性同余是同一件事:后者是前者的子问题。
下面给出通解。考虑
a x + b y = c , ax + by = c, a x + b y = c ,
其中 a a a 、b b b 、c c c 已知,x x x 、y y y 待求。
第一步:特解。 由扩展欧几里得算法,存在 x 0 x_0 x 0 、y 0 y_0 y 0 使得 a x 0 + b y 0 = gcd ( a , b ) ax_0+by_0=\gcd(a,b) a x 0 + b y 0 = g cd( a , b ) 。
第二步:通解形状。 若 c c c 是 gcd ( a , b ) \gcd(a,b) g cd( a , b ) 的倍数,设 c = k ⋅ gcd ( a , b ) c=k\cdot\gcd(a,b) c = k ⋅ g cd( a , b ) ,则 a x 0 k + b y 0 k = c ax_0k+by_0k=c a x 0 k + b y 0 k = c 给出一个特解。对任意整数 t t t ,
a ( x 0 k + t b / d ) + b ( y 0 k − t a / d ) = c , a\bigl(x_0k + t b/d\bigr) + b\bigl(y_0k - t a/d\bigr) = c, a ( x 0 k + t b / d ) + b ( y 0 k − t a / d ) = c ,
其中 d = gcd ( a , b ) d=\gcd(a,b) d = g cd( a , b ) 。加在 x x x 上的 b / d b/d b / d 倍与减在 y y y 上的 a / d a/d a / d 倍,乘上 a a a 、b b b 后恰好抵消。
第三步:通解。
x = k x 0 + t ( b d ) , y = k y 0 − t ( a d ) , x = kx_0 + t\left(\frac{b}{d}\right),\qquad
y = ky_0 - t\left(\frac{a}{d}\right), x = k x 0 + t ( d b ) , y = k y 0 − t ( d a ) ,
其中 t t t 为任意整数,d = gcd ( a , b ) d=\gcd(a,b) d = g cd( a , b ) 。若 a a a 、b b b 互质,解集仍然无穷。
推论 线性丢番图方程何时有解
若 gcd ( a , b ) = 1 \gcd(a,b)=1 g cd( a , b ) = 1 ,则方程对任意整数 c c c 都有整数解,因为 1 1 1 整除一切整数。若 c c c 不是 gcd ( a , b ) \gcd(a,b) g cd( a , b ) 的倍数,则没有整数解。一般地,当 gcd ( a , b ) ∣ c \gcd(a,b)\mid c g cd( a , b ) ∣ c 时有整数解。
有了丢番图方程,线性同余可以立刻对上。
命题 把线性同余化成丢番图方程
解线性同余是解线性丢番图方程的子问题。求 c = s a + t b c=sa+tb c = s a + t b 等价于解这个丢番图方程,也等价于求 a x ≡ c ( m o d b ) ax\equiv c\pmod{b} a x ≡ c ( mod b ) 。
证明
a x ≡ c ( m o d b ) ax\equiv c\pmod{b} a x ≡ c ( mod b ) 表示 a x m o d b = c m o d b ax\bmod b=c\bmod b a x mod b = c mod b 。由带余除法,a x = q 1 b + r ax=q_1b+r a x = q 1 b + r 、c = q 2 b + r c=q_2b+r c = q 2 b + r ,于是 c − q 2 b = a x − q 1 b c-q_2b=ax-q_1b c − q 2 b = a x − q 1 b ,即 c = a x + ( q 2 − q 1 ) b c=ax+(q_2-q_1)b c = a x + ( q 2 − q 1 ) b ,其中 q 2 − q 1 ∈ Z q_2-q_1\in\mathbb{Z} q 2 − q 1 ∈ Z 。因此解线性同余就是解一个丢番图方程。
例 解 400 z ≡ 8 ( m o d 1022 ) 400z\equiv 8\pmod{1022} 400 z ≡ 8 ( mod 1022 ) 解 400 z ≡ 8 ( m o d 1022 ) 400z\equiv 8 \pmod{1022} 400 z ≡ 8 ( mod 1022 ) 。
直接当成丢番图方程 8 = 400 x + 1022 y 8=400x+1022y 8 = 400 x + 1022 y 。先用扩展欧几里得算法求 gcd:
1022 = 2 × 400 + 222 , 400 = 1 × 222 + 178 , 222 = 1 × 178 + 44 , 178 = 4 × 44 + 2 , 44 = 22 × 2 + 0. \begin{aligned}
1022&=2\times400+222,\\
400&=1\times 222+178,\\
222&=1\times 178+44,\\
178&=4\times 44+2,\\
44&=22\times2+0.
\end{aligned} 1022 400 222 178 44 = 2 × 400 + 222 , = 1 × 222 + 178 , = 1 × 178 + 44 , = 4 × 44 + 2 , = 22 × 2 + 0.
由贝祖定理反代得到 2 = 23 × 400 − 9 × 1022 2=23\times 400-9\times 1022 2 = 23 × 400 − 9 × 1022 。8 8 8 是 2 2 2 的倍数,故 8 = − 36 × 1022 + 92 × 400 8=-36\times 1022+92\times 400 8 = − 36 × 1022 + 92 × 400 ,特解为 x = 92 x=92 x = 92 、y = − 36 y=-36 y = − 36 。通解为
x = k ⋅ 92 + t ( 1022 gcd ( 400 , 1022 ) ) , y = k ⋅ ( − 36 ) + t ( 400 gcd ( 400 , 1022 ) ) . \begin{aligned}
x&=k\cdot 92+t\left(\frac{1022}{\gcd(400,1022)}\right),\\
y&=k\cdot(-36)+t\left(\frac{400}{\gcd(400,1022)}\right).
\end{aligned} x y = k ⋅ 92 + t ( g cd( 400 , 1022 ) 1022 ) , = k ⋅ ( − 36 ) + t ( g cd( 400 , 1022 ) 400 ) .
中国剩余定理
上一小节把线性同余对应到单个线性方程。现在对应到方程组。回忆:线性方程组是关于同一批未知数的若干线性方程。
定义 线性方程组
在实数里,n n n 个未知数 x 1 , x 2 , … , x n x_1,x_2,\ldots,x_n x 1 , x 2 , … , x n 的 n n n 个线性方程可以写成
a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 ⋮ a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n , \begin{aligned}
a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n &= b_1 \\
a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n &= b_2 \\
\vdots &\\
a_{n1}x_1 + a_{n2}x_2 + \cdots + a_{nn}x_n &= b_n,
\end{aligned} a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n ⋮ a n 1 x 1 + a n 2 x 2 + ⋯ + a nn x n = b 1 = b 2 = b n , 其中 a i j a_{ij} a ij 、b i b_i b i 为实数。
定义 线性同余方程组
类似地,线性同余方程组是同一批未知数上、在不同模下的若干线性同余。n n n 个未知数的 n n n 个线性同余可以写成
a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n ≡ b 1 ( m o d m 1 ) a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n ≡ b 2 ( m o d m 2 ) ⋮ a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n ≡ b n ( m o d m n ) , \begin{aligned}
a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n &\equiv b_1 \pmod{m_1} \\
a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n &\equiv b_2 \pmod{m_2} \\
\vdots &\\
a_{n1}x_1 + a_{n2}x_2 + \cdots + a_{nn}x_n &\equiv b_n \pmod{m_n},
\end{aligned} a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n ⋮ a n 1 x 1 + a n 2 x 2 + ⋯ + a nn x n ≡ b 1 ( mod m 1 ) ≡ b 2 ( mod m 2 ) ≡ b n ( mod m n ) , 其中 a i j a_{ij} a ij 、b i b_i b i 、m i m_i m i 为整数。目标是同时满足所有方程或同余的未知数取值。
一般情形需要矩阵和线性代数。和丢番图方程一样,这里只处理一种基本形状,对应的定理就是中国剩余定理 。公元一世纪,孙子问:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?
写成同余组就是
x ≡ 2 ( m o d 3 ) , x ≡ 3 ( m o d 5 ) , x ≡ 2 ( m o d 7 ) . \begin{aligned}
x&\equiv2\pmod{3},\\
x&\equiv3\pmod{5},\\
x&\equiv2\pmod{7}.
\end{aligned} x x x ≡ 2 ( mod 3 ) , ≡ 3 ( mod 5 ) , ≡ 2 ( mod 7 ) .
求这种组的解的算法,就是中国剩余定理。
定理 中国剩余定理
设 m 1 , m 2 , … , m n m_1,m_2,\ldots,m_n m 1 , m 2 , … , m n 是大于 1 1 1 且两两互质的正整数,a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a 1 , a 2 , … , a n 是任意整数。则方程组
x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) ⋮ x ≡ a n ( m o d m n ) \begin{aligned}
x&\equiv a_1\pmod{m_1}\\
x&\equiv a_2 \pmod{m_2}\\
\vdots&\\
x&\equiv a_n \pmod{m_n}
\end{aligned} x x ⋮ x ≡ a 1 ( mod m 1 ) ≡ a 2 ( mod m 2 ) ≡ a n ( mod m n ) 模 M = m 1 m 2 ⋯ m n M=m_1m_2\cdots m_n M = m 1 m 2 ⋯ m n 有唯一解。也就是说,存在解 x x x 满足 0 ≤ x < M 0\le x<M 0 ≤ x < M ,而其余解都与这个解模 M M M 同余。
证明
需要证明解存在,并且模 M M M 唯一。存在性通过构造给出。
存在性。 对 k = 1 , 2 , … , n k=1,2,\ldots,n k = 1 , 2 , … , n ,令
M k = M m k = m 1 m 2 ⋯ m k − 1 m k + 1 ⋯ m n , M_k = \frac{M}{m_k} = m_1m_2 \cdots m_{k-1}m_{k+1} \cdots m_n, M k = m k M = m 1 m 2 ⋯ m k − 1 m k + 1 ⋯ m n , 即除 m k m_k m k 以外所有模的乘积。当 i ≠ k i\neq k i = k 时 m i m_i m i 与 m k m_k m k 没有大于 1 1 1 的公因数,故 gcd ( m k , M k ) = 1 \gcd(m_k,M_k)=1 g cd( m k , M k ) = 1 。由贝祖恒等式,存在 y k y_k y k 、z k z_k z k 使得 M k y k + m k z k = 1 M_ky_k+m_kz_k=1 M k y k + m k z k = 1 ,从而 M k y k ≡ 1 ( m o d m k ) M_ky_k\equiv 1\pmod{m_k} M k y k ≡ 1 ( mod m k ) ,y k y_k y k 是 M k M_k M k 模 m k m_k m k 的逆。构造
x = a 1 M 1 y 1 + a 2 M 2 y 2 + ⋯ + a n M n y n . x = a_1M_1y_1 + a_2M_2y_2 + \cdots + a_nM_ny_n. x = a 1 M 1 y 1 + a 2 M 2 y 2 + ⋯ + a n M n y n . 当 j ≠ k j\neq k j = k 时 M j ≡ 0 ( m o d m k ) M_j\equiv 0\pmod{m_k} M j ≡ 0 ( mod m k ) ,故和式中除第 k k k 项外都模 m k m_k m k 同余于 0 0 0 。又 M k y k ≡ 1 ( m o d m k ) M_ky_k\equiv 1\pmod{m_k} M k y k ≡ 1 ( mod m k ) ,于是
x ≡ a k M k y k ≡ a k ( m o d m k ) , k = 1 , 2 , … , n . x \equiv a_kM_ky_k \equiv a_k \pmod{m_k},\qquad k=1,2,\ldots,n. x ≡ a k M k y k ≡ a k ( mod m k ) , k = 1 , 2 , … , n . 因此 x x x 同时满足全部 n n n 个同余。
模 M M M 的唯一性。 设 x x x 与 x ′ x' x ′ 都是解。则对每个 k k k ,x ≡ a k ( m o d m k ) x\equiv a_k\pmod{m_k} x ≡ a k ( mod m k ) 且 x ′ ≡ a k ( m o d m k ) x'\equiv a_k\pmod{m_k} x ′ ≡ a k ( mod m k ) ,从而 x ≡ x ′ ( m o d m k ) x\equiv x'\pmod{m_k} x ≡ x ′ ( mod m k ) 。因为 m 1 , … , m n m_1,\ldots,m_n m 1 , … , m n 两两互质,故 x ≡ x ′ ( m o d M ) x\equiv x'\pmod{M} x ≡ x ′ ( mod M ) ,其中 M = m 1 m 2 ⋯ m n M=m_1m_2\cdots m_n M = m 1 m 2 ⋯ m n 。
例 用公式解孙子问题
解
x ≡ 2 ( m o d 3 ) x ≡ 3 ( m o d 5 ) x ≡ 2 ( m o d 7 ) , \begin{aligned}
x &\equiv 2 \pmod{3} \\
x &\equiv 3 \pmod{5} \\
x &\equiv 2 \pmod{7},
\end{aligned} x x x ≡ 2 ( mod 3 ) ≡ 3 ( mod 5 ) ≡ 2 ( mod 7 ) , 其中 m 1 = 3 m_1=3 m 1 = 3 、m 2 = 5 m_2=5 m 2 = 5 、m 3 = 7 m_3=7 m 3 = 7 两两互质。
由中国剩余定理,
x ≡ a 1 M 1 y 1 + a 2 M 2 y 2 + a 3 M 3 y 3 ( m o d m 1 m 2 m 3 ) , x \equiv a_1M_1y_1 + a_2M_2y_2 + a_3M_3y_3 \pmod{m_1m_2m_3}, x ≡ a 1 M 1 y 1 + a 2 M 2 y 2 + a 3 M 3 y 3 ( mod m 1 m 2 m 3 ) , 其中 M i = m 1 m 2 m 3 / m i M_i=m_1m_2m_3/m_i M i = m 1 m 2 m 3 / m i ,且 M i y i ≡ 1 ( m o d m i ) M_iy_i\equiv 1\pmod{m_i} M i y i ≡ 1 ( mod m i ) 。计算得
x ≡ a 1 M 1 y 1 + a 2 M 2 y 2 + a 3 M 3 y 3 = 2 ⋅ 35 ⋅ 2 + 3 ⋅ 21 ⋅ 1 + 2 ⋅ 15 ⋅ 1 = 233 ≡ 23 ( m o d 105 ) . \begin{aligned}
x&\equiv a_{1}M_{1}y_{1}+a_{2}M_{2}y_{2}+a_{3}M_{3}y_{3}\\
& =2\cdot35\cdot2+3\cdot21\cdot1+2\cdot15\cdot1 \\
&=233\equiv23\pmod{105}.
\end{aligned} x ≡ a 1 M 1 y 1 + a 2 M 2 y 2 + a 3 M 3 y 3 = 2 ⋅ 35 ⋅ 2 + 3 ⋅ 21 ⋅ 1 + 2 ⋅ 15 ⋅ 1 = 233 ≡ 23 ( mod 105 ) . x ≡ 23 ( m o d 105 ) x\equiv 23\pmod{105} x ≡ 23 ( mod 105 ) 是最小的正整数,被 3 3 3 除余 2 2 2 ,被 5 5 5 除余 3 3 3 ,被 7 7 7 除余 2 2 2 。
这是一般公式,但求模逆并不总是轻松,规模一大计算也不理想。下面用回代作为捷径。
例 用回代解同一组同余
仍解
x ≡ 2 ( m o d 3 ) x ≡ 3 ( m o d 5 ) x ≡ 2 ( m o d 7 ) . \begin{aligned}
x &\equiv 2 \pmod{3} \\
x &\equiv 3 \pmod{5} \\
x &\equiv 2 \pmod{7}.
\end{aligned} x x x ≡ 2 ( mod 3 ) ≡ 3 ( mod 5 ) ≡ 2 ( mod 7 ) . 由同余定义,x ≡ 2 ( m o d 3 ) x\equiv 2\pmod{3} x ≡ 2 ( mod 3 ) 即 x = 3 i + 2 x=3i+2 x = 3 i + 2 。代入第二条:3 i + 2 ≡ 3 ( m o d 5 ) 3i+2\equiv 3\pmod{5} 3 i + 2 ≡ 3 ( mod 5 ) ,两边减 2 2 2 得 3 i ≡ 1 ( m o d 5 ) 3i\equiv 1\pmod{5} 3 i ≡ 1 ( mod 5 ) 。于是 i i i 是 3 3 3 模 5 5 5 的逆,最小正整数解是 i = 2 i=2 i = 2 ,即 i ≡ 2 ( m o d 5 ) i\equiv 2\pmod{5} i ≡ 2 ( mod 5 ) 。再写 i = 5 j + 2 i=5j+2 i = 5 j + 2 ,代入 x = 3 i + 2 x=3i+2 x = 3 i + 2 得 x = 15 j + 8 x=15j+8 x = 15 j + 8 。再代入第三条:15 j + 8 ≡ 2 ( m o d 7 ) 15j+8\equiv 2\pmod{7} 15 j + 8 ≡ 2 ( mod 7 ) 。因为 8 ≡ 1 ( m o d 7 ) 8\equiv 1\pmod{7} 8 ≡ 1 ( mod 7 ) ,故 15 j ≡ 1 ( m o d 7 ) 15j\equiv 1\pmod{7} 15 j ≡ 1 ( mod 7 ) 。于是 j j j 是 15 15 15 模 7 7 7 的逆,最小正整数是 1 1 1 ,即 j ≡ 1 ( m o d 7 ) j\equiv 1\pmod{7} j ≡ 1 ( mod 7 ) 。再写 j = 7 k + 1 j=7k+1 j = 7 k + 1 ,代入 x = 15 j + 8 x=15j+8 x = 15 j + 8 得 x = 15 ( 7 k + 1 ) + 8 x=15(7k+1)+8 x = 15 ( 7 k + 1 ) + 8 ,即
x = 105 k + 23 , x = 105k + 23, x = 105 k + 23 , 也就是 x ≡ 23 ( m o d 105 ) x\equiv 23\pmod{105} x ≡ 23 ( mod 105 ) 。这正是该同余组的解。
费马小定理
费马小定理以法国数学家皮埃尔·德·费马命名,他在 1640 1640 1640 年陈述了这一结果。它是数论的基本定理,在密码学、计算机科学和其他领域都有大量应用:把很大的幂先模一个素数再算,往往能把计算量压下来。
定理 费马小定理
设 p p p 为素数,a a a 为不被 p p p 整除的整数。则
a p − 1 ≡ 1 ( m o d p ) . a^{p-1} \equiv 1 \pmod{p}. a p − 1 ≡ 1 ( mod p ) . 也就是说,把 a a a 的 p − 1 p-1 p − 1 次幂除以 p p p ,余数总是 1 1 1 。
前面用快速模幂计算 b n m o d m b^n\bmod m b n mod m 。费马小定理提供另一条路,有时更快。
证明
设 p p p 为素数,a a a 不被 p p p 整除。考虑集合 { 1 , 2 , … , p − 1 } \{1,2,\ldots,p-1\} { 1 , 2 , … , p − 1 } ,把每个元素乘以 a a a 再模 p p p 。这个操作是该集合的一个置换:若 a x ≡ a y ( m o d p ) ax\equiv ay\pmod{p} a x ≡ a y ( mod p ) ,则 a ( x − y ) ≡ 0 ( m o d p ) a(x-y)\equiv 0\pmod{p} a ( x − y ) ≡ 0 ( mod p ) ,而 p p p 不整除 a a a ,故 x ≡ y ( m o d p ) x\equiv y\pmod{p} x ≡ y ( mod p ) 。
因此 { a ⋅ 1 , a ⋅ 2 , … , a ⋅ ( p − 1 ) } \{a\cdot 1,a\cdot 2,\ldots,a\cdot(p-1)\} { a ⋅ 1 , a ⋅ 2 , … , a ⋅ ( p − 1 )} 模 p p p 后正好是 { 1 , 2 , … , p − 1 } \{1,2,\ldots,p-1\} { 1 , 2 , … , p − 1 } 的重排。两边所有元素相乘:
∏ i = 1 p − 1 ( a ⋅ i ) ≡ ∏ i = 1 p − 1 i ( m o d p ) , \prod_{i=1}^{p-1} (a \cdot i) \equiv \prod_{i=1}^{p-1} i \pmod{p}, i = 1 ∏ p − 1 ( a ⋅ i ) ≡ i = 1 ∏ p − 1 i ( mod p ) , 即
a p − 1 ∏ i = 1 p − 1 i ≡ ∏ i = 1 p − 1 i ( m o d p ) . a^{p-1} \prod_{i=1}^{p-1} i \equiv \prod_{i=1}^{p-1} i \pmod{p}. a p − 1 i = 1 ∏ p − 1 i ≡ i = 1 ∏ p − 1 i ( mod p ) . ∏ i = 1 p − 1 i \prod_{i=1}^{p-1} i ∏ i = 1 p − 1 i 不被 p p p 整除,可以约掉,得到 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod{p} a p − 1 ≡ 1 ( mod p ) 。
下表帮助看清定理在说什么。取 p = 7 p=7 p = 7 ,表中行号是 a a a ,列号是指数 b b b ,格中是 a b m o d 7 a^b\bmod 7 a b mod 7 。每隔 6 6 6 列就会出现整列都满足 a b ≡ 1 ( m o d 7 ) a^b\equiv 1\pmod{7} a b ≡ 1 ( mod 7 ) 的情形,而 6 = p − 1 6=p-1 6 = p − 1 。
a \ b a \backslash b a \ b 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 1 1 1 2 2 2 4 4 4 1 1 1 2 2 2 4 4 4 1 1 1 3 3 3 1 1 1 3 3 3 2 2 2 6 6 6 4 4 4 5 5 5 1 1 1 4 4 4 1 1 1 4 4 4 2 2 2 1 1 1 4 4 4 2 2 2 1 1 1 5 5 5 1 1 1 5 5 5 4 4 4 6 6 6 2 2 2 3 3 3 1 1 1 6 6 6 1 1 1 6 6 6 1 1 1 6 6 6 1 1 1 6 6 6 1 1 1
例 用费马小定理计算 3 100 m o d 7 3^{100}\bmod 7 3 100 mod 7 用费马小定理计算 3 100 ( m o d 7 ) 3^{100} \pmod{7} 3 100 ( mod 7 ) 。
解 先降指数再算余数
先核对条件:7 7 7 是素数,3 3 3 不被 7 7 7 整除。由费马小定理,3 7 − 1 ≡ 1 ( m o d 7 ) 3^{7-1}\equiv 1\pmod{7} 3 7 − 1 ≡ 1 ( mod 7 ) ,即 3 6 ≡ 1 ( m o d 7 ) 3^6\equiv 1\pmod{7} 3 6 ≡ 1 ( mod 7 ) 。于是
3 100 = ( 3 6 ) 16 ⋅ 3 4 ≡ 1 16 ⋅ 3 4 ( m o d 7 ) ≡ 1 ⋅ 81 ( m o d 7 ) ≡ 4 ( m o d 7 ) . \begin{aligned}
3^{100} &= (3^6)^{16} \cdot 3^4 \\
&\equiv 1^{16} \cdot 3^4 \pmod{7} \\
&\equiv 1 \cdot 81 \pmod{7} \\
&\equiv 4 \pmod{7}.
\end{aligned} 3 100 = ( 3 6 ) 16 ⋅ 3 4 ≡ 1 16 ⋅ 3 4 ( mod 7 ) ≡ 1 ⋅ 81 ( mod 7 ) ≡ 4 ( mod 7 ) . 因此 3 100 ≡ 4 ( m o d 7 ) 3^{100}\equiv 4\pmod{7} 3 100 ≡ 4 ( mod 7 ) 。
步骤可以再拆开:7 7 7 是素数且 7 ∤ 3 7\nmid 3 7 ∤ 3 ,故 3 6 ≡ 1 ( m o d 7 ) 3^6\equiv 1\pmod{7} 3 6 ≡ 1 ( mod 7 ) 。把指数写成 100 = 6 ⋅ 16 + 4 100=6\cdot 16+4 100 = 6 ⋅ 16 + 4 ,于是 3 100 = ( 3 6 ) 16 ⋅ 3 4 3^{100}=(3^6)^{16}\cdot 3^4 3 100 = ( 3 6 ) 16 ⋅ 3 4 。前一段变成 1 16 = 1 1^{16}=1 1 16 = 1 ,后一段 81 ≡ 4 ( m o d 7 ) 81\equiv 4\pmod{7} 81 ≡ 4 ( mod 7 ) ,相乘仍得 4 4 4 。
练习 gcd 与两个线性同余是否可解
用欧几里得算法求 504 504 504 与 385 385 385 的最大公因数,并考虑:
是否存在整数 y y y 使得 504 y ≡ 10 ( m o d 385 ) 504y \equiv 10 \pmod{385} 504 y ≡ 10 ( mod 385 ) ?若存在,找出一个;若不存在,说明原因。
是否存在整数 z z z 使得 504 z ≡ 7 ( m o d 385 ) 504z \equiv 7 \pmod{385} 504 z ≡ 7 ( mod 385 ) ?若存在,找出一个;若不存在,说明原因。
解 扩展欧几里得算法
504 = 1 × 385 + 119 , 385 = 3 × 119 + 28 , 119 = 4 × 28 + 7 , 28 = 4 × 7 + 0. \begin{aligned}
504 & =1\times 385+119,\\
385 & =3\times 119+28,\\
119 & =4\times 28+7,\\
28 & =4\times 7+0.
\end{aligned} 504 385 119 28 = 1 × 385 + 119 , = 3 × 119 + 28 , = 4 × 28 + 7 , = 4 × 7 + 0. 故 gcd ( 504 , 385 ) = 7 \gcd(504,385)=7 g cd( 504 , 385 ) = 7 。解线性同余等价于解线性丢番图方程,即求
10 = 504 x + 385 y , 7 = 504 x + 385 y . \begin{aligned}
10 &=504x+385y,\\
7 &= 504x+385y.
\end{aligned} 10 7 = 504 x + 385 y , = 504 x + 385 y . 同余 504 z ≡ 7 ( m o d 385 ) 504z \equiv 7 \pmod{385} 504 z ≡ 7 ( mod 385 ) 可先换成 119 z ≡ 7 ( m o d 385 ) 119z \equiv 7 \pmod{385} 119 z ≡ 7 ( mod 385 ) ,因为 504 ≡ 119 ( m o d 385 ) 504\equiv 119\pmod{385} 504 ≡ 119 ( mod 385 ) 。gcd ( 119 , 385 ) = 7 \gcd(119,385)=7 g cd( 119 , 385 ) = 7 整除 7 7 7 ,故有解。两边除以 7 7 7 得 17 z ≡ 1 ( m o d 55 ) 17z\equiv 1\pmod{55} 17 z ≡ 1 ( mod 55 ) 。试验 17 17 17 的倍数,发现 17 ⋅ 13 ≡ 1 ( m o d 55 ) 17\cdot 13\equiv 1\pmod{55} 17 ⋅ 13 ≡ 1 ( mod 55 ) ,故 z = 13 z=13 z = 13 是一个解。
第一个方程没有整数解,因为 7 ∤ 10 7\nmid 10 7 ∤ 10 。
通解仍用前面的公式:
{ x = k × x 0 + t ( 385 / gcd ( 504 , 385 ) ) , y = k × y 0 + t ( 504 / gcd ( 504 , 385 ) ) , \begin{cases}
x = k \times x_0 + t \bigl(385/\gcd(504,385)\bigr),\\
y = k \times y_0 + t \bigl(504/\gcd(504,385)\bigr),
\end{cases} { x = k × x 0 + t ( 385/ g cd( 504 , 385 ) ) , y = k × y 0 + t ( 504/ g cd( 504 , 385 ) ) , 其中 x 0 x_0 x 0 、y 0 y_0 y 0 是一组特解。把扩展欧几里得的各行反代,得到 gcd ( 504 , 385 ) = 13 × 504 − 17 × 385 \gcd(504,385)=13\times 504-17\times 385 g cd( 504 , 385 ) = 13 × 504 − 17 × 385 。于是当方程有解时,
{ x = k × 13 + t ( 385 / gcd ( 504 , 385 ) ) , y = k × ( − 17 ) + t ( 504 / gcd ( 504 , 385 ) ) \begin{cases}
x = k \times 13 + t \bigl(385/\gcd(504,385)\bigr),\\
y = k \times (-17) + t \bigl(504/\gcd(504,385)\bigr)
\end{cases} { x = k × 13 + t ( 385/ g cd( 504 , 385 ) ) , y = k × ( − 17 ) + t ( 504/ g cd( 504 , 385 ) ) 就是通解。
评论