前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【科普向】纸上得来终觉浅,绝知此事要躬行:从π的355/113近似说起

【科普向】纸上得来终觉浅,绝知此事要躬行:从π的355/113近似说起

作者头像
陈学谦
发布2021-11-23 11:00:38
7590
发布2021-11-23 11:00:38
举报
文章被收录于专栏:学谦数据运营学谦数据运营

本文提供了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之间,所以分子的大小范围控制在3*7和4*7之间,略微减少不必要的计算:

以下开始用python代码进行计算

首先,我们需要获取比较准确的π近似值,这里导入math函数:

代码语言:javascript
复制
import math
pi_val = math.pi
print(pi_val)

#output:3.141592653589793

第二步,给定任意的数字a,分子从3a增大到4a,获得分数,计算分数与π的差值,选取差值最小的那一个,就是以a为分母能够得到的最接近π的分数。

由于分子从3a增大到4a的过程中,在得到最接近π的分数之前,差值是逐渐变小的,而在得到最接近π的分数之后,差值是逐渐变大的,因此我们设定,当新获取的差值比之前最小的差值大的时候,循环停止(当然,如果你愿意,你甚至可以将设置范围为3.14a增大到3.15a之间的整数):

代码语言:javascript
复制
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

测试一下:

这样我们就可以循环地找分母在某个数以内最接近于π的分数了:

代码语言:javascript
复制
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呢。

如果时间允许,你还可以继续往后算算,分母为100万以内的最接近π的分数,不过,使用上面的代码可能需要较长的等待:

关注【学谦数据运营】,回复“圆周率”获取改进版高效计算代码。

结语

那么,祖冲之究竟是用什么办法把π算到小数点后第七位,又是怎样找到既精确又方便记忆的近似值355/113呢?估计是用python算的吧。这是至今仍困惑着数学家的一个谜。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PowerBI生命管理大师学谦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档