猫史档案馆


【圆周率】又一个神奇的计算圆周率的程序 能计算到小数点后数十万位

用户:SunshineCodeSunshineCode查看:13 回复:8 评论:13 创建时间:2019-06-05T20:20:23


最近搜到一个C语言程序,是这样的:

#include<stdio.h>
#include<iostream>


using namespace std;

int main(void)

{

    printf("本程序每四位数输出结果,如果请求计算的位数不是4的整数倍,最后输出可能会少1~3位");

    long a[2]={956,80},b[2]={57121,25},i=0,j,k,p,q,r,s=2,t,u,v,N,M=10000;
    printf("计算公式:Machin%4cpi=16arctan(1/5)-4arctan(1/239)\n计算到的位数?\n",32,32);
    cin>>N,N=N/4+3;
    long *pi=new long[N],*e=new long[N];
    while(i<N)pi[i++]=0;
    while(--s+1)
    {
        for(*e=a[k=s],i=N;--i;)e[i]=0;
        for(q=1;j=i-1,i<N;e[i]?0:++i,q+=2,k=!k)
        for(r=v=0;++j<N;pi[j]+=k?u:-u)u=(t=v*M+(e[j]=(p=r*M+e[j])/b[s]))/q,r=p%b[s],v=t%q;
    }
    while(--i)(pi[i]=(t=pi[i]+s)%M)<0?pi[i]+=M,s=t/M-1:s=t/M;
    for(cout<<"3.";++i<N-2;)printf("%04ld",pi[i]);
    delete []pi,delete []e,cin.ignore(),cin.ignore();
    return 0;
}

 

这个程序可以计算制定位数的圆周率值,

你想计算到多少位,只要你有耐心,电脑有足够的运行内存,都是可以算出来的。

迭代速度很快,计算到小数点后20000位,只用了两三秒(xp32位机)

所用的计算公式是马青公式:

pi = 16 arctan 1/5 + 4 arctan 1/239

*其中arctan又可写作arctg

arctan是反正切,计算公式为:

arctan x = x - 1/3 x^3 + 1/5 x^5 - 1/7 x^7 + 1/9 x^9 - ...

 

这个公式计算圆周率收敛速度很快,每迭代一次就能计算出1.39位的圆周率值。

于是,我最近就在据这个程序研究如何在编程猫中实现。


回复

上一页1 页 / 共 1下一页
SunshineCodeSunshineCode

注:"^"表示次方

点赞0


评论


SunshineCodeSunshineCode

补:原C程序改写Python:

def show(n,plt_type='pie'):

result = f(n)

a = pd.Series([int(i) for i in result])

b = a.value_counts()

if plt_type=='pie':

plt.figure(figsize=(10,8))

plt.pie(b,labels=b.index,explode=[0.05]*10,shadow=True,autopct='%1.1f%%')

plt.show()

elif plt_type=='bar':

plt.figure(figsize=(10,8))

plt.bar(b.index,b.values)

plt.show()

else:

print('Type Wrong')

 

点赞0


评论


FATAL_ERRORFATAL_ERROR

这么好的东西

没人顶顶可惜了emotion_编程猫_点赞

点赞0


评论


急_开_锁_办_证810864急_开_锁_办_证810864

少侠,这是你要的编程猫实现。编程猫没有函数返回值,要实现高级一点的功能复用的话,都要靠全局变量传递结果,很难受。center_image

其实对于演示圆周率的近似计算,Nilakantha级数和著名的Basel问题(Leonhard Euler最早给出证明的那个)都更适合用于在Scratch类的软件中练习。

点赞0


评论


啊不嘟啊不嘟

####################导入时间模块
import time
###############计算当前时间
time1=time.time()
################算法根据马青公式计算圆周率####################


number = int(input('请输入想要计算到小数点后的位数:'))
print('计算中......')

# 多计算10位,防止尾数取舍的影响
number1 = number+10

# 算到小数点后number1位
b = 10**number1
# 求b*4/5的首项
x1 = b*4//5
# 求b/-239的首项
x2 = b//-239

# 求第一大项
he = x1+x2
#设置下面循环的终点,即共计算n项
number *= 2

#循环初值=3,末值2n,步长=2
for i in range(3,number,2):
    # 求每个含1/5的项及符号
    x1 //= -25
    # 求每个含1/239的项及符号
    x2 //= -57121
    # 求两项之和
    x = (x1+x2) // i
    # 求总和
    he += x

#求出π
    pi = he*4
#舍掉后十位
    pi //= 10**10


#输出圆周率π的值
f = open('pi.txt','w')
paistring=str(pi)
result=paistring[0]+str('.')+paistring[1:len(paistring)]
f.write(result)
f.close()
time2=time.time()
print('π的值已存储到当前目录的pi.txt文件中')
print ('总共耗时:'+ str((time2 - time1)//1) + '秒')

python版本

点赞1


评论


啊不嘟啊不嘟

源码编辑器版

点赞0


评论


SunshineCodeSunshineCode

分享一下:现在我们研究计算圆周率,都是用的马青公式,因为这个公式比较简单,容易实现,不过这个公式收敛速度较慢,每迭代一次只能算出1.39位的圆周率值。如果大家想要超高精度超高速度的圆周率计算,不妨使用丘德诺夫斯基公式。这个公式每迭代一次就能计算出14位的圆周率值。

代码如下(python):

# -*- coding: UTF-8 -*-
# 丘德诺夫斯基法計算高精度圓周率程序
# Calculating PI with Chudnovsky-Series
# Author: Idealguy,2018, Shanghai
#
import time

# In following functions, High-Prec Nums are both amplified 10**n
# pre-defined: Base=10**n
#

def Sqrt10005(): # Sqrt(10005L) by Imitate-Manual Method
n1=0
c=10002499687 #100.02499687
mc=8; m=mc
f1=10**mc
f2=f1*f1
a=10005*f2-c*c
while mc<n:
a*=f2
b=c*2*f1
d=a//b
c=c*f1+d
a-=d*(b+d)
mc+=m
if mc*2>n: m=n-mc
else: m=mc
f1=10**m
f2=f1*f1
n1+=1
return c

# Main Program
#
print ("Chudnovsky法計算高精度圓周率程序")
while 1:
n=int(input('計算位數[1..50000],0:退出:'))
if n<=10: break
n+=2
base=10**n
t=time.clock()
# Start Calculating
A=13591409*base; B=A
c3=13591409
i=1
while abs(A)>5:
c1=((108-72*i)*i-46)*i+5
c2=10939058860032000*i**3
c4=c3; c3+=545140134
i+=1
A=A*c1*c3//(c2*c4) # Must in form: A=A*...
B+=A
p=426880*base*Sqrt10005()//B//100
# Post access
print ("用時= %8.3f 秒" % (time.clock()-t))
s=input('是否显示结果(Y/N):')
if (s=='Y')|(s=="y"): print ("PI="+str(p))
# end

点赞0


评论


啊不嘟啊不嘟

# -*- coding: UTF-8 -*-
# 丘德诺夫斯基法計算高精度圓周率程序
# Calculating PI with Chudnovsky-Series
# Author: Idealguy,2018, Shanghai
#
import time
  
# In following functions, High-Prec Nums are both amplified 10**n
# pre-defined: Base=10**n
# 
  
def Sqrt10005():  # Sqrt(10005L) by Imitate-Manual Method
    n1=0
    c=10002499687 #100.02499687
    mc=8; m=mc
    f1=10**mc
    f2=f1*f1
    a=10005*f2-c*c
    while mc<n:
        a*=f2
        b=c*2*f1
        d=a//b
        c=c*f1+d
        a-=d*(b+d)
        mc+=m
        if mc*2>n: m=n-mc
        else: m=mc
        f1=10**m
        f2=f1*f1
        n1+=1
    return c
  
# Main Program
#
print ("Chudnovsky法計算高精度圓周率程序")
while 1:
    n=int(input('計算位數[1..50000],0:退出:'))
##    if n<=10: break
    n+=2
    base=10**n
    t=time.clock()
    # Start Calculating
    A=13591409*base; B=A
    c3=13591409
    i=1
    while abs(A)>5:
        c1=((108-72*i)*i-46)*i+5
        c2=10939058860032000*i**3
        c4=c3; c3+=545140134
        i+=1
        A=A*c1*c3//(c2*c4)   # Must in form: A=A*...
        B+=A
    p=426880*base*Sqrt10005()//B//100
    # Post access
    print ("用時= %8.3f 秒" % (time.clock()-t))
    with open('pi.txt','w') as f:
        f.write('3.'+str(p)[1:n-1])
    print('pi的值已保存到当前目录:pi.txt')
# end

 

点赞0


评论