020 Integer Representations and Algorithms
所有整数都可以用任意大于 1 的基底表示出来。日常常用十进制,计算机领域常用二进制、八进制和十六进制。
Representations of Integers
定理 1 令 是任意大于 1 的正整数。如果 是正整数,那么可以唯一的表示为 其中 是非负整数, 是小于 的整数,且 。
证明:证明过程需要使用归纳法,会在 5.1 节证明。TODO link
这种表示方法称为基为 的展开式,写作 。一般情况下,十进制表示不写下标。
计算机中常用二进制(binary
)八进制(octal
)和十六进制(hexadecimal
)。其中十六进制需要十六个字符来表示一个数,超过了十进制的十个数字,后面使用 A,B,C,D,E,F
表示。
下面的算法描述了如何将 表示为基为 的展开形式 。
procedure - base b expansion(n, b: positive integers with b > 1)
q := n
k := 0
while q != 0
a_k := q mod b
q := q div b
k := k + 1
{(a_{k−1}, ... , a1, a0)_b is the base b expansion of n}
return (a_{k−1}, ... , a1, a0)
八进制和十六进制的每个字符是二的整数倍,所以相互之间的转化非常容易,见下表。
Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
Hexadecimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
Octal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | |
Binary | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
Algorithms for Integer Operations
这一个小节我们考察 的算术运算,并使用比特个数(数字的二进制长度)来分析算法的时间复杂度。
加法运算,时间复杂度是 。
procedure - add(a, b: positive integers)
{the binary expansions of a and b are (a_{n-1}a_{n-2}\cdots a_2a_1a_0)_2 and (b_{n-1}b_{n-2}\cdots b_2b_1b_0)_2, respectively}
c := 0
for j := 0 to n − 1
d := (a_j + b_j + c)∕2
s_j := a_j + b_j + c − 2d
c := d
sn := c
{the binary expansion of the sum is (s_ns_{n−1} ... s_0)_2}
return (s0, s1, ... , s_n)
乘法运算,时间复杂度是 。
procedure - multiply(a, b: positive integers)
{the binary expansions of a and b are (a_{n-1}a_{n-2}\cdots a_2a_1a_0)_2 and (b_{n-1}b_{n-2}\cdots b_2b_1b_0)_2, respectively}
for j := 0 to n − 1
if b_j = 1 then c_j := a shifted j places
else c_j := 0
{c_0, c_1, ... , c_{n−1} are the partial products}
p := 0
for j := 0 to n − 1
p := add(p, c_j)
{p is the value of ab}
return p
除法和模运算,时间复杂度是 。
procedure - division algorithm(a: integer, d: positive integer)
q := 0
r := |a|
while r >= d
r := r − d
q := q + 1
if a < 0 and r > 0 then
r := d − r
q := −(q + 1)
{q = a div d is the quotient, r = a mod d is the remainder}
return (q, r)
Modular Exponentiation
下面讨论高效地计算 ,其中 都很大。如果直接计算,效率低,且 非常大,浪费内存。
一个直观的方法是利用 4.1 节的定理 5 的推论 2 连续计算 ,最终得到 。这种算法需要 次乘法,当 非常大的时候计算也比较耗时。
下面是快速计算法。令 ,那么 由于 是 0 或者 1,那么只需要知道 等值即可。这样,只需要 次乘法。实际算法在计算过程中需要不断地模 。整个算法非常高效,只需要 次比特操作。