数学 / 实数 · 从数轴的空位到浮点的间距 / 有理数与小数展开 待审核 2 / 5
长除法 · 循环节

有理数与小数展开

有理数是能写成 p/qp/q 的数(ppqq 为整数且 q0q \ne 0)。把这个分数按长除法展开成小数,得到的形态只有两种:有限,或者从某位起无限循环。无限不循环的展开被排除在外,这条排除的理由短得出乎意料——只需数一数余数能取几个值。

本页给出这条等价的两个方向,再往下问一个更细的问题:循环节有多长?答案不在长除法里,而在分母的因数分解与一个模运算的阶上。

1 · 长除法的余数与鸽巢原理

长除法的每一步都是同一个动作:把当前余数乘 1010,除以 qq,商得一位小数,留下新余数。新余数是「乘 1010 之后对 qq 取余」的结果,只能落在 {0,1,,q1}\{0, 1, \dots, q-1\}qq 个值里。

定理 1.1 任何有理数 p/qp/q 的十进制展开或是有限小数,或是从某位起无限循环的小数。

证明 展开的每一步由当前余数唯一决定:余数相同则此后的商位与余数序列完全相同。余数取值只有 qq 种,故前 q+1q+1 步里必有两步的余数相同(鸽巢原理)。若中途出现余数 00,展开终止,得有限小数;否则某个余数第二次出现,从它起整段重复,两次出现之间的那串商位即循环节。∎

图 1-1 · p/qp/q 的长除法逐步展开,右侧表格记录每一步的余数、商位与新余数;某个余数再次出现时,商里对应的一段以顶部横线标出。可调 ppqq 或点选预设分数。

这条论证只用到余数的取值个数,与十进制没有关系。换成二进制,余数照样只有 qq 种,结论同样成立,只是「有限」的判据从「分母只含 2255」换成「分母只含 22」。这个换底的后果在 浮点数:实数在代码里的残影 里有直接的用处。

警示 · 引擎最初只在非负输入上验过。computeLongDivision(-1, 2) 返回的 digit5-5decimalString 把它拼成了字面的 -1.-5:JS 的 % 对负数给出负余数,负号一路渗进了每一位商。lab 把分子的输入下界钉在 00,所以页面上从未暴露过。现在展开只在绝对值上做,符号单独记在 negative 字段里。

2 · 循环小数还原成分数

反方向同样成立:任何有限小数或循环小数都是有理数。有限小数直接按位数取分母,0.75=75/100=3/40.75 = 75/100 = 3/4。循环小数的标准手法是错位相减——乘上 1010 的适当次幂使两式的循环部分对齐,相减即把无限的尾巴消掉。

例 2.1x=0.1234x = 0.12\overline{34},即 0.123434340.12343434\dots。前置段长 22、循环节长 22,故取 10210^210410^4 两个倍数:104x=1234.343410^4 x = 1234.3434\dots102x=12.343410^2 x = 12.3434\dots,相减得 9900x=12229900x = 1222,即 x=611/4950x = 611/4950

同一个结果也可以由等比数列求和给出:0.12340.12\overline{34} 的循环部分是首项 34/10434/10^4、公比 10210^{-2} 的等比数列之和,即 (34/104)11102=34/9900(34/10^4) \cdot \frac{1}{1 - 10^{-2}} = 34/9900,加上前置段 12/10012/100 得同一个分数(等比数列求和的公式见 等比数列与前 n 项和)。两条路殊途同归:错位相减是把求和公式的推导过程就地做了一遍。

小数展开的形态与数系归属一一对应,判据是「是否无限且不循环」,与小数位的多少无关。
小数展开形态 例子 归类
有限小数 0.50.50.750.75 有理数
无限循环小数 0.3330.333\dots22/7=3.14285714285722/7 = 3.142857\,142857\dots 有理数
无限不循环小数 2=1.41421356\sqrt 2 = 1.41421356\dotsπ=3.14159265\pi = 3.14159265\dots 无理数

3 · 循环节的长度

定理 1.1 只保证循环会出现,没说循环节有多长。这件事完全由约到最简之后的分母决定,而且分工清楚:把分母写成 q=2a5bqq = 2^a 5^b q',其中 qq'1010 互素。

定理 3.1p/qp/q 已约到最简,q=2a5bqq = 2^a 5^b q'gcd(q,10)=1\gcd(q', 10) = 1。则前置非循环段的长度为 max(a,b)\max(a, b),循环节的长度为 1010 在模 qq' 下的乘法阶,即使 10k1(modq)10^k \equiv 1 \pmod{q'} 成立的最小正整数 kkq=1q' = 1 时展开有限。

由此得到纯循环与混循环的分界:a=b=0a = b = 0(分母不含 2255)时小数点后立刻进入循环,称纯循环小数;否则前 max(a,b)\max(a, b) 位不参与循环,称混循环小数。1/71/7 纯循环,1/14=0.07142851/14 = 0.0\overline{714285} 混循环且前置段一位,1/281/28 前置段两位——三者的循环节都是 66 位,因为剥掉 2255 之后剩下的都是 77

图 3-1 · 分母的因数分解、前置段与循环节长度,以及 qq22121121 的循环节长度色块阵列(颜色越深越长,白格为有限小数)。可点选任一格或直接输入分母。

循环节长度的上限是 q1q' - 1,在 1010 是模 qq' 的原根时取到:1/71/7661/171/1716161/971/9796961/1931/193192192。这样的素数在 200200 以内共 1717 个:7,17,19,23,29,47,59,61,97,109,113,131,149,167,179,181,1937, 17, 19, 23, 29, 47, 59, 61, 97, 109, 113, 131, 149, 167, 179, 181, 193。上限之外的情形更常见,而且落差可以很大:1/131/13 的循环节是 66 而不是 12121/1011/101 只有 44239239 是素数,238=2×7×17238 = 2 \times 7 \times 17 有六个因数,1010 的阶取到了其中最小的 77,于是 1/2391/239 的循环节只有 77 位。阶必整除 φ(q)\varphi(q'),具体落在哪个因数上要算过才知道。

core/real-numbers.ts 里的长除法设了 200200 步上限,q=223q = 223 是第一个展不完的分母(1/2231/223 的循环节长 222222)。这条上限比看起来更容易撞上:lab 允许的分母到 99999999,其中 52175217 个(52.2%52.2\%)的展开超过 200200 位,最长的是 1/99671/9967,循环节 99669966 位。定理 3.1 那条路不做除法,只做一次因数分解与一次求阶,因此色块阵列上每一格都算得出来,长除法那一栏则会截断显示并注明未闭合。

4 · 等于一的那个循环小数

0.999=10.999\dots = 1 是严格相等,不是「无限接近」。至少有三条独立的论证。

错位相减:设 x=0.999x = 0.999\dots,则 10x=9.99910x = 9.999\dots,两式相减得 9x=99x = 9,故 x=1x = 1

等比数列求和:0.9990.999\dots 是首项 9/109/10、公比 1/101/10 的无穷等比数列之和,9/1011/10=1\frac{9/10}{1 - 1/10} = 1

反证:若 x=0.999x = 0.999\dots11 不等,则 1x1 - x 是一个正数,必存在正整数 nn 使 1x>10n1 - x > 10^{-n}。但 xx 的前 nn 位小数全是 99,故 x110nx \ge 1 - 10^{-n},即 1x10n1 - x \le 10^{-n},矛盾。

这条等式说明十进制表示不是一一对应的:分母只含 2255 的分数各有两种无限小数写法,一种以 00 结尾、一种以 99 结尾(0.5=0.49990.5 = 0.4999\dots)。除此之外没有别的重复写法,所以「小数展开」与「实数」之间那个几乎是双射的对应,差的仅是这一族可数多个点。反过来看,本页的还原公式在 0.90.\overline{9} 上给出的分数是 1/11/1 而不是别的什么,单测把这一条钉住了。

5 · 参考文献

  1. Repeating decimal. Wikipedia. 循环小数的记法、还原公式与循环节长度。https://en.wikipedia.org/wiki/Repeating_decimal
  2. Multiplicative order. Wikipedia. 乘法阶的定义与它整除 φ(n)\varphi(n) 这一性质。https://en.wikipedia.org/wiki/Multiplicative_order
  3. Full reptend prime. Wikipedia. 使 1010 成为原根的素数,即循环节取到上限的那些分母。https://en.wikipedia.org/wiki/Full_reptend_prime
  4. 0.999…. Wikipedia. 这条等式的多种证明与常见误解。https://en.wikipedia.org/wiki/0.999...