找回密码
 注册
搜索
热搜: 回贴
  • 前程无忧官网首页 有什么好的平台可以
  • 最新的销售平台 互联网营销的平台有哪
  • 制作网页的基本流程 网页制作和网页设
  • 【帝国CMS】输出带序号的列表(数字排
  • 网站建设公司 三一,中联,极东泵车的
  • 织梦 建站 织梦网站模版后台怎么更改
  • 云服务官网 哪些网站有免费的简历模板
  • 如何建网站要什么条件 建网站要用什么
  • 吉林市移动公司电话 吉林省退休人员网
  • 设计类毕业论文 网站设计与实现毕业论
查看: 2639|回复: 9

[转帖]计算圆周率 Pi (π)值,精确到小数点后 10000 位,只需要30多句代码! ...

[复制链接]
发表于 2009-11-6 22:29:20 | 显示全部楼层 |阅读模式 IP:江苏扬州
大家都知道π=3.1415926……无穷多位, 历史上很多人都在计算这个数, 一直认为是一个非常复杂的问题。现在有了电脑, 这个问题就简单了。电脑可以利用级数计算出很多高精度的值, 有关级数的问题请参考《高等数学》,以下是比较有名的有关π的级数:  其中有些计算起来很复杂, 我们可以选用第三个, 比较简单, 并且收敛的非常快。因为计算π值, 而这个公式是计算π/2的, 我们把它变形: π = 2 + 2/3 + 2/3*2/5 + 2/3*2/5*3/7 + ...


对于级数, 我们先做个简单测试, 暂时不要求精度: 用 C++ Builder 新建一个工程, 在 Form 上放一个 Memo1 和 一个 Button1, 在 Button1 的 OnClick 事件写:
void __fastcall TForm1::Button1Click(TObject *Sender) { double x=2, z=2; int a=1, b=3; while(z>1e-15) { z = z*a/b; x += z; a++; b+=2; } Memo1->Text = AnsiString().sprintf("Pi=%.13f", x); }

按Button1在Memo1显示出执行结果: Pi=3.1415926535898


这个程序太简单了, 而且 double 的精度很低, 只能计算到小数点后 10 几位。把上面的程序改造一下, 让它精确到小数点后面 1000 位再测试一下: 在 Form 上再放一个按钮 Button2, 在这个按钮的 OnClick 事件写:
void __fastcall TForm1::Button2Click(TObject *Sender) { const ARRSIZE=1010, DISPCNT=1000; //定义数组大小,显示位数 char x[ARRSIZE], z[ARRSIZE]; //x[0] x[1] . x[2] x[3] x[4] .... x[ARRSIZE-1] int a=1, b=3, c, d, Run=1, Cnt=0; memset(x,0,ARRSIZE); memset(z,0,ARRSIZE); x[1] = 2; z[1] = 2; while(Run && (++Cnt<200000000)) { //z*=a; d = 0; for(int i=ARRSIZE-1; i>0; i--) { c = z*a + d; z = c % 10; d = c / 10; } //z/=b; d = 0; for(int i=0; i<ARRSIZE; i++) { c = z+d*10; z = c / b; d = c % b; } //x+=z; Run = 0; for(int i=ARRSIZE-1; i>0; i--) { c = x + z; x = c%10; x[i-1] += c/10; Run |= z; } a++; b+=2; } Memo1->Text = AnsiString().sprintf("计算了 %d 次\r\n",Cnt); Memo1->Text = Memo1->Text + AnsiString().sprintf("Pi=%d%d.\r\n", x[0],x[1]); for(int i=0; i<DISPCNT; i++) { if(i && ((i%100)==0)) Memo1->Text = Memo1->Text + "\r\n"; Memo1->Text = Memo1->Text + (int)x[i+2]; } }
按 Button2 执行结果: Pi=03. 1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196 4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273 7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094 3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912 9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132 0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235 4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859 5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303 5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989


这下心理有底了, 是不是改变数组大小就可以计算更多位数呢?答案是肯定的。如果把定义数组大小和显示位数改为: const ARRSIZE=10100, DISPCNT=10000; //定义数组大小,显示位数执行结果精度可达 10000 位: Pi=03. 1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196 4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273 7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094 3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912 9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132 0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235 4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859 5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303 5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989 3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151 ... 限于篇幅, 这里就省略了, 还是留给你自己来算吧! 5020141020672358502007245225632651341055924019027421624843914035998953539459094407046912091409387001 2645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678

提高精度的原理: 以上程序的原理是利用数组把计算结果保存起来, 其中数组每一项保存10进制数的一位, 小数点定位在数组第1个数和第二个数之间, 即小数点前面2位整数, 其余都是小数位。利用电脑模拟四则运算的笔算方法来实现高精度的数据计算,没想到最原始的方法竟然是精度最高的。  
发表于 2009-11-6 22:29:23 | 显示全部楼层 IP:江苏扬州

http://www.jason314.com/index.html
计算圆周率
 
古今中外,许多人致力于圆周率的研究与计算。为了计算出圆周率的越来越好的近似值,一代代的数学家为这个神秘的数贡献了无数的时间与心血。十九世纪前,圆周率的计算进展相当缓慢,十九世纪后,计算圆周率的世界纪录频频创新。整个十九世纪,可以说是圆周率的手工计算量最大的世纪。进入二十世纪,随着计算机的发明,圆周率的计算有了突飞猛进。借助于超级计算机,人们已经得到了圆周率的2061亿位精度。历史上最马拉松式的计算,其一是德国的Ludolph Van Ceulen,他几乎耗尽了一生的时间,计算到圆的内接正262边形,于1609年得到了圆周率的35位精度值,以至于圆周率在德国被称为Ludolph数;其二是英国的William Shanks,他耗费了15年的光阴,在1874年算出了圆周率的小数点后707位。可惜,后人发现,他从第528位开始就算错了。把圆周率的数值算得这么精确,实际意义并不大。现代科技领域使用的圆周率值,有十几位已经足够了。如果用Ludolph Van Ceulen算出的35位精度的圆周率值,来计算一个能把太阳系包起来的一个圆的周长,误差还不到质子直径的百万分之一。以前的人计算圆周率,是要探究圆周率是否循环小数。自从1761年Lambert证明了圆周率是无理数,1882年Lindemann证明了圆周率是超越数后,圆周率的神秘面纱就被揭开了。现在的人计算圆周率, 多数是为了验证计算机的计算能力,还有,就是为了兴趣。
 
圆周率的计算方法 圆周率的计算历史 圆周率的最新计算记录 PC机上的计算 120亿位圆周率下载 圆周率的探索者
回复

使用道具 举报

发表于 2009-11-6 22:29:26 | 显示全部楼层 IP:江苏扬州
1 亿位????
按1 秒背一位的话,就算不吃不喝不睡觉,也需要3年的时间!
回复

使用道具 举报

发表于 2009-11-6 22:29:29 | 显示全部楼层 IP:江苏扬州
呵呵 有趣
回复

使用道具 举报

发表于 2009-11-6 22:29:32 | 显示全部楼层 IP:江苏扬州
这就是符号计算的威力,类似的软件设计思想maple,matlab
回复

使用道具 举报

发表于 2009-11-6 22:29:35 | 显示全部楼层 IP:江苏扬州
我晕了,120亿位的有6.4G,Terrible!!!
回复

使用道具 举报

发表于 2009-11-6 22:29:38 | 显示全部楼层 IP:江苏扬州
我只知道有人可以背到10000位左右。。。
我也可以背到50位左右啊
回复

使用道具 举报

发表于 2009-11-6 22:29:41 | 显示全部楼层 IP:江苏扬州
呵呵,好象有能背到小数点后1亿位的奇人哩!
回复

使用道具 举报

发表于 2010-1-12 18:05:08 | 显示全部楼层 IP:四川成都
阿额~~对自己好点~别难为自己 ~~~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-29 11:27 , Processed in 0.242153 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表