本文提供了python计算最接近π的分数的程序与说明,阅读仅需要5min。
提起中国古代的数学成就,就都会想起南北朝时期的祖冲之。
提起祖冲之,大家最熟悉的就是他在计算圆周率π方面的杰出贡献,祖冲之在前人研究圆周率的基础上进一步得出精确到小数点后7位的结果,给出不足近似值3.1415926和过剩近似值3.1415927,即
3.1415926<π<3.1415927
他还得到两个近似分数值,密率355/113和约率22/7。密率355/113传到了日本,日本人将它叫做“祖率”。
很多人知道用355/113表示π是一项了不起的贡献,但是,它的奇妙之处很少有人能够了解,或者说不全。
首先,它非常精确:
355/113=3.1415929204···
而
π=3.1415926535···
因此,两者之间的误差不足0.000000267···,即2.67e-07。
但是它足够精确吗,根据祖冲之得到的3.1415926<π<3.1415927,他可以得到一个更加精确的分数:
314159265/100000000=3.14159265
作为π的近似值,因为误差不超过0.00000005,即5e-08,比2.67e-07精确了一个数量级。
那祖冲之为什么不用314159265/100000000或者62831853/20000000来作为密率呢?
因为这个分母过大,且不容易记住。
355/113这个分数的分母足够小,且记起来非常简单,113355,从中间切开,一半放在分母一半放在分子就行了。
我们知道,如果给定了一个数字作为分母,那么它一定会有一个最接近于π的分子,比如分母是7,那么以7为分母的一系列分数中,我们可以找到最接近于π的那一个:
因为我们知道π首先介于3和4之间,所以我们分子的大小范围控制在37和47之间,略微减少不必要的计算:
首先,我们需要获取比较准确的π近似值:
import math pi_val = math.pi print(pi_val) #output:3.141592653589793
第二步,给定任意的数字a,分子从3a增大到4a,获得分数,计算分数与π的差值,选取差值最小的那一个,就是以a为分母能够得到的最接近π的分数。
由于分子从3a增大到4a的过程中,在得到最接近π的分数之前,差值是逐渐变小的,而在得到最接近π的分数之后,差值是逐渐变大的,因此我们设定,当新获取的差值比之前最小的差值大的时候,循环停止(当然,如果你愿意,你甚至可以将设置范围为3.14a增大到3.15a之间的整数):
def get_fraction_min_of_one_denominator(a): error_min=10 i_min=0 for i in range(3*a,4*a): fraction_val=i/a error=abs(fraction_val-pi_val) if error<error_min: error_min=error i_min=i if error>error_min: break fraction_min=str(i_min)+"/"+str(a) print("分母为"+str(a)+"最接近于π的分数为:"+fraction_min+",误差为:"+str(error_min)) return error_min,fraction_min
测试一下:
这样我们就可以循环地找分母在某个数以内最接近于π的分数了:
def get_fractions_closest_to_pi(a): for i in range(1,a+1): error,fraction=get_fraction_min_of_one_denominator(i) if i==1: error_min=error fraction_min=fraction if error<error_min: print("在所有分母不超过"+str(i-1)+"的分数中,与π最接近的分数为:"+fraction_min+",误差为:"+str(error_min)) error_min=error fraction_min=fraction print("在所有分母不超过"+str(a)+"的分数中,与π最接近的分数为:"+fraction_min+",误差为:"+str(error_min))
比如我们可以选取从1循环到100:
在所有分母不超过100的分数中,与π最接近的分数为:311/99,误差为:0.00017851217565167943
也就是说,如果祖冲之想用分母为两位数的分母表示π,最准确的分母是311/99,这个好像也不难记。
如果是1000以内呢?
哦豁,我们发现,分母在100以内时,随着分母的增大,很快就会有一个新的分数更加接近π,在113以内与π最接近的分数是355/113,然而分母从113开始增大,一直增大到1000,竟然就没有一个分数比355/113还要接近π。
我们再来测试一下4位数,10000以内:
哦豁,在分母不超10000以内,竟然还是没有任何一个分数比355/113更加接近π。
一直到分母为16604时,才出现了另一个比355/113更加接近π的分数:52163/16604
然而如果你仔细看,52163/16604比355/113并没有更加精确多少,误差数量级差不多都是2.66e-07
而如果你想记住52163/16604这个分数,恐怕还不如直接记住3.1415926呢。
但是祖冲之究竟是用什么办法把π算到小数点后第七位,又是怎样找到既精确又方便记忆的近似值355/113呢?这是至今仍困惑着数学家的一个谜。
圆周率的两个近似值:约率(22/7)和密率(355/113)都可以通过连分数得到。
令 , (取整函数),,这样我们可以得到一个整数数列 ,且满足
的前几项分别是3,7,15,1,292,1,1,1,2,1,3,1,14,3,3,23,……
只取第一项,可得 ;
取前两项,可得,即约率;
取前三项,可得;
取前四项,可得,即密率;
取前五项,可得。
很明显,从第五项开始,分数就变得复杂了,只取前四项得到的355/113就是形式上简单,数值上又接近圆周率的值。