你的生日在圆周率后的多少位&圆周率后一千万位

Python源代码

此代码目前需要先将第八行所示的pai*******.txt文件,保存在python文件的同级目录,方可正常运行。

import time


def file():
    global num
    global txtCont
    global fp
    # 读取已有圆周率小数点数据文件
    fp = open('pai5000000.txt', 'r+')
    txtCont = fp.read()


def save():
    global paiStr
    # file()
    if len(paiStr) > len(txtCont):
        print("保存成功!已保存了小数点后" + str(len(paiStr) - 1) + "位")
        paiStr = paiStr[len(txtCont):]
        fp.write(paiStr)
    else:
        # print("无需更新数据!",end="")
        print("pai.txt目前保存了小数点后" + str(len(txtCont) - 1) + "位")
    fp.close()


def pai():
    global num
    global paiStr
    global t21
    num = input("输入想要计算的圆周率小数点后的位数:")
    t1 = time.time()
    if not num.isdigit():
        print("请输入整数!!")
        return pai()
    num = int(num)
    if num > len(txtCont) - 1:
        # 多计算10位 防止尾数取舍的影响
        t = num + 10
        n = num
        # 为算到小数点后t位 两边乘以10^t
        b = 10 ** t
        # 取整 求含4/5的首项
        x1 = b * 4 // 5
        # 取整 求含1/239的首项
        x2 = b // -239
        # 求第一大项
        s = x1 + x2
        # 设置下面循环的终点 即共计算n项
        n *= 2
        # 循环初值=3 终点=n 步长=2
        for i in range(3, n, 2):
            # 取整 求每个含1/5的项及符号
            x1 //= -25
            # 取整 求每个含1/239的项及符号
            x2 //= -57121
            # 求两项之和 除以对应因子 取整
            x = (x1 + x2) // i
            # 求总和
            s += x
        # 求圆周率
        painum = s * 4
        # 舍掉后十位
        painum //= 10 ** 10
        # 输出圆周率的值 不带小数点
        paiStr = str(painum)
        print("得到圆周率个数位3及小数点后" + str(num) + "位:" + paiStr)
        save()
    else:
        # print("pai.txt目前保存了小数点后" + str(len(txtCont) - 1) + "位:" + txtCont)
        print("得到小数点后" + str(num) + "位:" + txtCont[0:num])
        print("目前保存了小数点后" + str(len(txtCont) - 1) + "位")
    t2 = time.time()
    t21 = t2 - t1


def judge():
    global temp
    temp = 0
    wantStr = str(input("想要查询位于圆周率小数点后" + str(num) + "位中的哪串数字?"))
    t3 = time.time()
    if wantStr in txtCont[0:num]:
        print("该串数字第一次出现位于圆周率小数点后" + str(txtCont[0:num].index(wantStr)) + "位!")
        print("该串数字在圆周率小数点后" + str(num) + "位中一共出现了" + str(txtCont[0:num].count(wantStr)) + "次!")
        # print("--------------------")
        temp = 1
    else:
        print("该串数字不在圆周率后" + str(num) + "位中!")
        # print("--------------------")
        temp = 0
    t4 = time.time()
    t43 = t4 - t3
    print("本次程序运行花费" + str(t43 + t21) + "秒")
    print("--------------------")


def run():
    file()
    pai()
    # save()
    while True:
        judge()
        if temp:
            print("再次", end="")
            pai()
        else:
            print("重新", end="")
            pai()


if __name__ == "__main__":
    run()

例:输入

输入想要计算的圆周率小数点后的位数:5000000

输出:

31415926…………6461971
目前保存了小数点后5000000位
想要查询位于圆周率小数点后5000000位中的哪串数字?

再输入:

想要查询位于圆周率小数点后5000000位中的哪串数字?980209

输入:

该串数字第一次出现位于圆周率小数点后549739位!
该串数字在圆周率小数点后5000000位中一共出现了9次!
本次程序运行花费0.07444524765014648秒
--------------------
再次输入想要计算的圆周率小数点后的位数:

马青公式

思路

  1. 判断字符串A是否是字符串B的子串
  2. 圆周率计算方法:Machin公式
  3. 输入想要求取的圆周率小数点后位数
  4. 判断pai.txt内是否已经保存了想要的位数
  5. 若有:则省略计算过程、若无:则运行Machin公式并把结果保存到pai.txt
  6. 输入想要判断的数串
  7. 判断过程死循环,需手动结束程序

可计算圆周率的公式方法

Machin公式
莱布尼茨级数:级数的收敛太慢,不适合于计算高精度的圆周率。
三角乘积
Zeta函数的偶数值
Dirichlet beta函数的奇数值
莫比乌斯的Dirichlet级数
Dirichlet eta函数
拉马努金公式:收敛的速度异常地快,这公式后来在2000年演变成最快的公式
楚德蔑落夫公式

Machin缺点

Machin公式计算精度高,但计算效率较低

圆周率后一百万位&五百万位&一千万位

标签: