问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

计算圆周率的五种方法

创作时间:
作者:
@小白创作中心

计算圆周率的五种方法

引用
CSDN
1.
https://blog.csdn.net/zhang_dengyu/article/details/136756168

圆周率(π)是数学中最著名的常数之一,它表示圆的周长与其直径的比例。自古以来,人类就一直在寻找更精确的π值。从古希腊的阿基米德到现代的超级计算机,计算π的方法不断演进。本文将介绍五种计算圆周率的方法,从古老的割圆术到现代的数学公式,每种方法都展示了人类智慧的结晶。

割圆法

相关知识

割圆术是中国魏晋时期的数学家刘徽于公元263年在《九章算术注》中提出的。刘徽形容他的“割圆术”说:“割之弥细,所失弥少,割之又割,以至于不可割,则与圆合体,而无所失矣。”这包含了求极限的思想。通过求圆内接正多边形的周长来近似求圆的周长,并使正多边形的周长无限接近圆的周长,进而求得较为精确的圆周率。

设圆半径为1,圆内接正6边形边长也为1, 可如下计算正12边形的边长:

  • OC = sqrt(1 - (AB/2)^2)
  • CD = 1 - OC
  • 新的边长AD值为:sqrt((AB/2)^2 + CD^2)

编程实现

import math

def cutting_circle(n):  # n为分割次数
    side_length = 1  # 初始边长
    edges = 6  # 初始边数

    def length(x):  # x为AB
        h = math.sqrt(1 - (x / 2) ** 2)  # h为OC
        return math.sqrt((x / 2) ** 2 + (1 - h) ** 2)

    for i in range(n):
        side_length = length(side_length)
        edges *= 2
        pi = side_length * edges / 2
    return edges, pi

if __name__ == '__main__':
    times = int(input())  # 割圆次数
    edges, pi = cutting_circle(times)  # 调用函数返回值
    print(f'分割{times}次,边数为{edges},圆周率为{pi:.6f}')
    print(f'math库中的圆周率常量值为{math.pi:.6f}')

无穷级数法

π是个超越数,圆周率的超越性否定了化圆为方这种尺规作图精确求解问题的可能性。有趣的是,π可以用无穷级数表示:

1 - 1/3 + 1/5 - 1/7 + ⋯ = π/4

左边的展式是一个无穷级数,被称为莱布尼茨级数(Leibniz),这个级数收敛到π/4,它通常也被称为格雷戈里-莱布尼茨级数,用以纪念莱布尼茨同时代的天文学家兼数学家詹姆斯·格雷戈里。

编程实现

def leibniz_of_pi(error):
    """接收用户输入的浮点数阈值为参数,返回圆周率值"""
    f = 1
    i = 1
    result = 0  # 初始化
    while 1 / (2 * i - 1) >= error:
        result += f * 1 / (2 * i - 1)
        f = -f
        i += 1
    return result * 4

if __name__ == '__main__':
    threshold = float(input())
    print("{:.8f}".format(leibniz_of_pi(threshold)))  # 保留小数点后八位

蒙特卡洛法

蒙特卡洛(Monte Carlo)方法是由数学家冯·诺伊曼提出的,诞生于上世纪40年代美国的“曼哈顿计划”。蒙特卡洛是一个地名,位于赌城摩纳哥,象征概率。蒙特卡洛方法的原理是通过大量随机样本,去了解一个系统,进而得到所要计算的值。

用蒙特卡洛方法计算圆周率π的原理如下:一个边长为2r的正方形内部相切一个半径为r的圆,圆的面积是πr^2,正方形的面积为4r^2,二者面积之比是π / 4。因为比值与r大小无关,所以可以假设半径r的值为1。

在这个正方形内部,随机产生n个点,坐标为(x, y),当随机点较多时,可以认为这些点服从均匀分布的规律。计算每个点与中心点的距离是否小于圆的半径(x^2 + y^2 < r^2),以此判断是否落在圆的内部。统计圆内的点数c,c与n的比值乘以4,就是π的值。理论上,n越大,计算的π值越准,但由于随机数不能保证完全均匀分布,所以蒙特卡洛法每次计算结果可能不同。

编程实现

import random

def monte_carlo_pi(num):
    """接收正整数为参数,表示随机点的数量,利用蒙特卡洛方法计算圆周率
    返回值为表示圆周率的浮点数"""
    c = 0
    for _ in range(num):
        x, y = random.uniform(-1, 1), random.uniform(-1, 1)
        if x * x + y * y <= 1:
            c += 1
    time = c * 4 / num
    return time

if __name__ == '__main__':
    sd = int(input())  # 读入随机数种子
    random.seed(sd)  # 设置随机数种子
    times = int(input())  # 输入正整数,表示产生点数量
    print(monte_carlo_pi(times))  # 输出圆周率值,浮点数

梅钦法

1706年,英国人约翰·梅钦(John Machin) 发明了一个用于计算π / 4值的公式:

π/4 = 4 * arctan(1/5) - arctan(1/239)

梅钦公式是格里高利/莱布尼茨计算的公式的变体,但是更实用,它的收敛速度显著增加,这使得它成为了更实用的计算的方法,虽然有若干种类梅钦(Machin-like)公式,但梅钦公式仍然是计算值的主要公式。

编程实现

from math import *

def machin_of_pi():
    """用梅钦级数计算圆周率,返回圆周率值"""
    pi = 4 * (4 * atan(1 / 5) - atan(1 / 239))
    return pi

if __name__ == '__main__':
    cal_pi = machin_of_pi()  # 调用判断类型的函数
    print(cal_pi)  # 输出函数运行结果

拉马努金法

拉马努金曾经提出过很多关于求π的公式,这些公式都有以下几个特点:等号右边的构造超乎常人想象,收敛速度极快!

π = 9801 / (2 * sqrt(2)) * Σ[k=0 to ∞] ((k!)^4 * (1103 + 26390k)) / (396^(4k) * (4k)!)

输入一个正整数n,根据些公式计算累加n次时的圆周率值。

编程要求

根据提示,在右侧编辑器补充代码,调用math库中的阶乘函数计算并输出圆周率的大小。

代码实现

from math import *

def ramanujan_of_pi(n):
    """接收一个正整数n为参数,用拉马努金公式的前n项计算圆周率并返回。"""
    c = 0
    b = 2 * sqrt(2) / 9801
    for i in range(n):
        a = pow(factorial(i), 4) * pow(396, 4 * i)  # 分母
        c += (factorial(4 * i) * (1103 + 26390 * i)) / a

    pi = 1 / (b * c)
    return pi

if __name__ == '__main__':
    n = int(input())
    cal_pi = ramanujan_of_pi(n)
    print(cal_pi)  # 输出函数运行结果
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号