圆周率十分重要,不仅仅是在数学理论上,即便在千年前的古代,工程上的需求,也迫切需要我们知道圆周率的尽量精确的数值。
求圆周率,有很多种方法,级数法就是简便易行的方法之一。
很多大牛已经把级数公式写好,并证明清楚,我们只要按公式求值就好了。
暂举几例:
π
2
6
=
1
1
2
+
1
2
2
+
1
3
2
+
.
.
.
\frac{\pi^2}{6} = \frac{1}{1^2} + \frac{1}{2^2} + \frac{1}{3^2} + ...
6π2=121+221+321+...
π
4
=
1
1
−
1
3
+
1
5
−
1
7
+
.
.
.
\frac{\pi}{4}=\frac{1}{1}-\frac{1}{3}+\frac{1}{5}-\frac{1}{7}+...
4π=11−31+51−71+...
π
=
3
+
4
2
×
3
×
4
−
4
4
×
5
×
6
+
4
6
×
7
×
8
−
.
.
.
\pi = 3 + \frac{4}{2\times3\times4} -\frac{4}{4\times5\times6}+\frac{4}{6\times7\times8}-...
π=3+2×3×44−4×5×64+6×7×84−...
请编程求 π \pi π 的值。
对每个公式单独写一个程序有点浪费代码,能不能做一个类似级数框架的东东,把这个方法的共性表达出来呢?
这些算法,无外乎是: 初始值 + 若干的小项,求和,最后再处理一下,得出
π
\pi
π 的值。
import math a1 = 0 def b1(n): return 1/(n*n) def c1(x): return math.sqrt(x*6) a2 = 0 def b2(n): return (-1)**(n+1)/(2*n-1) def c2(x): return 4*x a3 = 3 def b3(n): return (-1)**(n+1)*4/(2*n*(2*n+1)*(2*n+2)) def c3(x): return x # a: 初始值 # b: 通项公式(函数) # c: 后处理(函数) # n: 累加项数 def f(a,b,c,n): z = a for i in range(n): z += b(i+1) return c(z) #### print(f(a1,b1,c1,10000)) print(f(a2,b2,c2,10000)) print(f(a3,b3,c3,100))
我国古代数学家,发明了用割圆法求
π
\pi
π 值,其原理类似于近代的微积分。
具体做法:用圆内接正多边形的周长来近似地代替圆周。
多边形的边数越多,这种代替就越精确。
我们从正六边形开始,不断把边数加倍,很快就能获得高精度的
π
\pi
π 值
本题目的目标是,通过这种方法,把圆周率精确到小数点后6位。
计算的关键是,从当前的多边形如何计算加倍后的多边形的边长。
其实,只需要勾股定理就能搞定!
其原理如图:
h
=
1
−
(
a
2
)
2
h = \sqrt{1-\left(\frac{a}{2}\right)^2}
h=1−(2a)2
a
′
=
(
a
2
)
2
+
(
1
−
h
)
2
a' = \sqrt{\left(\frac{a}{2}\right)^2 + (1-h)^2}
a′=(2a)2+(1−h)2
import math #n: 当前的边数 #a: 当前的边长 def f(n,a): h = math.sqrt(1-(a/2)**2) a1 = math.sqrt((a/2)**2 + (1-h)**2) return (n*2, a1) ###### a = 1 n = 6 for i in range(10): n, a = f(n, a) print(n*a/2) print(math.pi)
如下图,边长为 1 的正方形内含有 1/4 个圆,显然,圆的半径为 1。
如果在正方形内随机产生点,落入圆内的概率 = 1/4 圆面积
请用程序产生大量的随机点,通过统计落入圆内的数目,估算 1/4 圆的面积
据此,推算出
π
\pi
π 值。
概率法很难获得高精度,而且每次运行结果都不一样。
但,概率法很重要,对于一些复杂的问题,如果没有办法做理论分析(比如复杂函数的积分),概率解有时也是很有用的。
判断一个点是否在圆内,只要看它到圆心的距离是否小于 1
import random # 随机产生散点 # 判断是否落在 1/4 圆内 def f(): x, y = random.random(), random.random() return x * x + y * y < 1 # n 次随机试验,求 pi 值 def pai(n): m = 0 # 落在圆内的次数 for i in range(n): if f(): m += 1 return m / n * 4 ############# print(pai(1000 * 1000))
其它的题目懒得贴了,自己下载吧:
《2021年新版-编程基础训练32题-附提示和答案》
链接: https://pan.baidu.com/s/1ZubWEUab1aCxEVWjBaRCDQ
提取码: aeha