例えば、円周率$\pi$は$3.14\ldots$なので$314/100$という分数で近似するということもできるが、$22/7=3.1428\ldots$の方が314や100よりも小さい数で近似できていて「良い」と言える。このような分数を見つける方法として、連分数を利用する方法が知られている。
from itertools import islice
from sympy import pi, continued_fraction_iterator, continued_fraction_convergents
list(continued_fraction_convergents(islice(continued_fraction_iterator(pi), 10)))
[3,
22/7,
333/106,
355/113,
103993/33102,
104348/33215,
208341/66317,
312689/99532,
833719/265381,
1146408/364913]
少し調べれば分かるが、$\pi$よりも小さい値と大きい値が交互に現れる。つまり、$3<\pi<22/7$, $333/106<\pi<355/113$というようにして、真の値$\pi$に近づいていく。そして、これが分数での「最良」の近似であることも知られている(どういう意味で「良い」のかの説明は専門書に譲る)。
どんな実数でも連分数を使うことが可能だが、特に(平方数でない$d$について)$\sqrt{d}$のような数において著しい特徴がある。循環小数では表せないが、循環連分数では表せるのだ。
continued_fraction_periodic(0, 1, 2)
[1, [2]]
は、$\sqrt{2}$が
$$
1+\frac{1}{2 + \frac{1}{2 + \frac{1}{2+\ddots}}}
$$
と表せることを意味している。
なお、sympy 1.13からはcontinued_fraction_convergentsに[1, [2]]のような形で連分数を指定することもできる。