📅  最后修改于: 2023-12-03 15:25:12.975000             🧑  作者: Mango
有理数是指可以表示成两个整数之比的数,包括整数、自然数和分数。如何将无限小数表示成有理数呢?接下来我们介绍一种较为简单的方法。
我们以8.765765765...为例,将其表示成n重循环小数,设8.765765765...的小数部分有m位不循环,有n位循环:
$$ 8.\overline{765} = 8.\underbrace{765\cdots 765}_{n\text{位}}\cdots $$
假设10的m+n次方乘以8.765765765...再减去10的m次方乘以8.765,则可得到以下式子:
$$ \begin{aligned} 10^{m+n} \times 8.\overline{765} - 10^m \times 8.765 &= 7765.\underbrace{765\cdots 765}{n\text{位}} - 8765 \ &= \underbrace{7\cdots 7}{m+n\text{位}}9000\cdots 0 \end{aligned} $$
因为$n>0$,所以$10^{m+n}-10^m$不为0,故可将左式整理得: $$ 8.\overline{765} = \frac{\underbrace{7\cdots 7}_{m+n\text{位}}9000\cdots 0}{10^{m+n}-10^m} $$
因此,8.765765765...可表示成$\frac{77657760}{999900}$,即为一个有理数。
我们可以将上述方法封装成函数:
def repeat_decimal_to_fraction(s: str):
"""
将一个循环小数(如3.14159...)表示为分数的形式。
输入示例:"8.765765765..."
输出示例:77657760/999900
"""
point_idx = s.find('.')
cycle_start_idx = s.find('(')
cycle_end_idx = s.find(')')
fraction = s[:point_idx] + s[point_idx + 1:cycle_start_idx] + s[cycle_start_idx + 1:cycle_end_idx] * 100
numerator = int(fraction) - int(s[:point_idx] + s[point_idx + 1:cycle_start_idx])
denominator = 10 ** (cycle_end_idx - cycle_start_idx - 1) * (10 ** (point_idx + len(s) - cycle_end_idx - 2) - 1)
return f"{numerator}/{denominator}"
在以上函数中,我们需要将小数点、循环节的开始和结束位置提取出来,然后根据上述方法计算分子和分母即可得到分数形式的结果。我们在调用该函数时,只需要将循环小数的字符串作为参数传入即可。
参考资料:
[1] 维基百科-无理数
[2] 如何把一个循环小数转化为分数形式