在历史长河中,求π一直是重要的研究问题。我们都知道π是一个无理数,所以永远无法求出其真值,只能不断地逼近它的真值。而我们的祖爷–祖冲之在千年前就计算出π介于3.1415926到3.1415927之间,在求π的历史上名副其实第一名。
据推测,祖爷是用割圆术求π的。割圆术讲的就是用圆的正N内割多边形的面积代替圆的面积,然后求π,现在我们想一下如果圆的半径为1,有内割圆正N多边形和外切圆正N多边形,那么就有
。
正N外切多边形面积>π>正N内割多边形面积
。有图为证,手画垃圾图,勉强看![851b7f01e9b5ba22dd337bb3d44bfb0b.png](https://i-blog.csdnimg.cn/blog_migrate/ecc09b31fc2bbcceddb71a95f8c583ae.png)
![1fbb2e6903fc6542bf4a8004fc28a5a9.png](https://i-blog.csdnimg.cn/blog_migrate/37163abddcefe6310c03d52240ce46e4.png)
如果N足够大,那么π就会越来越接近真值,这就是我们今天要讲的逼近法。实例如下:
"""计算π的值
用面积法夹逼π的值
割圆正多边面积
the statistics of this file:
lines(count) understand_level(h/m/l) classes(count) functions(count) fields(count)
000000000057 ----------------------h 00000000000000 0000000000000002 ~~~~~~~~~~~~~
"""import timeimport decimalimport math
__author__ = "于C同行"
D = decimal.Decimaldef tangent_circle_area(side_count, radius=1):"""计算圆的切正n多边形的面积
:param side_count: 正多边形的边数
:param radius: 圆的半径
:return: 正n多边形的面积
"""
pi = D(str(math.pi))
half_angle = pi/side_count
half_side_length = D(radius*math.tan(half_angle))
height = D(radius)
area = side_count*half_side_length*heightreturn areadef cut_circle_area(side_count, radius=1):"""计算圆的割正n多边形的面积
:param side_count: 正多边形的边数
:param radius: 圆的半径
:return: 正n多边形的面积
"""
pi = D(str(math.pi))
half_angle = pi/side_count
half_side_length = D(radius*math.sin(half_angle))
height = D(radius*math.cos(half_angle))
area = side_count*half_side_length*heightreturn areaif __name__ == '__main__':print(f'当前时间:{time.ctime()}')print()
n = 12288
min_pi = cut_circle_area(n)
max_pi = tangent_circle_area(n)print(f'真值π={math.pi}')print(f'在进行{n}次割圆与切圆计算后,得到{min_pi})
当N=12288时,结果如下:
![86fe97455ba90e1baf896e2857943040.png](https://i-blog.csdnimg.cn/blog_migrate/cb6c6acb7947af75126a96cfb50690f5.jpeg)
当N=100000000时,结果如下:
代码中用了decimal模块,只是为了计算时更准确,把它的decimal.Decimal类当成一个小数就行了。由于我们在计算正N多边形面积的时候使用了π来计算三角形的面积,所以这样计算正N多边形的面积是不对的。那么就又要夸一下祖爷了,祖爷用了最落后的工具却算出了高精度的值。不过,今天的主题只是为了了解求π的过程,至于如何准确地求三角形的面积,这个我们不考虑。