多种解法计算圆周率π

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计报告

学院、系:吉林大学珠海学院计算机科学与技术系专业名称:软件工程

课程设计科目C语言程序课程设计所在班级:

学生学号:

学生姓名:

指导教师:曾志平

完成时间:2012年3月-5月

题目:多种解法计算圆周率π

一、设计任务与目标

此问题求圆周率在之前所学的C语言中已经接触过,但是算法单一,采用级数,而且收敛较慢,故运行时间较长,此程序设计要解决的问题是如何实现高精度的运算,如何对结果进行输出,并且尝试采用不同的方法进行求解圆周率。

本次上机实践所使用的平台和相关软件。

平台:windows 7

相关软件:VC++6.0

二、方案设计与论证

随机数法求圆周率可以利用计算机中随机数函数模拟出两个0~1之间的浮点型点(x,y),建立直角坐标系思想,利用边长为1的正方形内切半径为0.5圆的方程(x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)<=0.25判断点是否在圆内,用计数器b保存在的点,如此模拟5000次。用落入圆内的点数b的4倍除以总的扔的点数N 用,可大概求出圆周率的值。一般来说,根据概率思想,N值越大,模拟次数越多,其求出来圆周率的值越接近真实的圆周率。

祖冲之迭代法因为圆内接正六边形边长等于半径的思想,故可以从正六边形出发,不断迭代,当正多边形边数增加时,其周长也逐渐逼近圆的周长,反过来即可求的一定精度的圆周率,设圆内接正六边形的边长为b,边数为i,利用公式

2

/2 i

x=进行迭代运算,为了提高精度,算法中对公式进行分开运算,求得边数为2i的圆内接正多边形后得出其周长,运用迭代后的正多边形周长减去迭代前的正多边形周长,获取其精度程度。如果最终求出的圆内接正多边形的周长,即接近圆的周长,最后利用数学公式即可以求出圆周率。输出其最后迭代后得圆内接正多边形的边数和圆周率即可。

用级数法求圆周率,定义一个a[400]的数组用于存储计算结果,从结果出发,因为其要输出一定精度的圆周率,若n值太大会造成计算冗余,利用数学中不等式确定其n项,用一个循环从n~1计算每一项的值并存储,1+n/(2n+1)用数组模拟手工乘除加法,除法1/(2n+1) ,相除后商为a[0],然后将余数乘以10,作

为被除数再除以除数取商为十分位,存于a[1],如此类推;乘法则每个数组乘以n,如果满十则向前面数组进一,再取其个位存储;加法因为加1,则直接可以加到a[0]上。然后保存计算结果后用该值计算n-1项,如此重复一直到第1项后按照格式输出每个数组元素即可。

附加题圆外切正多边形与圆内接正多边形算法相似,但是圆半径的长度为1时,其外切正六边形的边长为2*sqrt(3)/3,并且其迭代公式也相应的进行了改变,b=2*(sqrt(b*b+4)-2)/b;由于圆外切正多边形迭代后的周长小于迭代前的周长,故控制精度时用迭代前的正多边形周长减去迭代后的正多边形边长。

三、程序框图或流程图,程序清单与调用关系

main

jishu() neijie()waiqie()

suiji()

由主函数分别调用void suiji()(即课程第一小问,随机数函数),void neijie()(第二小问,内接正多边形法),void jishu()(第三小问,级数法),void waiqie()(外切正多边形法).

由于jishu函数的流程图过长,造成排版不便,故进行了分段和省略控制输出等部分流程图。

四、全部源程序清单

#include

#include

#include

#include

#define N 5000

void main()

{

void jishu();

void neijie();

void suiji();

void waiqie();

suiji();

printf("-------------------------------------------------------\n");

neijie();

printf("-------------------------------------------------------\n");

jishu();

printf("-------------------------------------------------------\n");

waiqie();

printf("-------------------------------------------------------\n");

}

void suiji()

{

double x,y;

int a=0,b=0;

srand(time(0));

while(a++<=N)//投5000次点

{

x=(double)rand()/RAND_MAX;//产生0~1之间的浮点数

y=(double)rand()/RAND_MAX;//产生0~1之间的浮点数

if((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)<=0.25)//判断所产生的点是否在圆内b++;//汇总落在圆内的点数

}

printf("用随机数法求得π=%lf\n",4.0*b/N);

}

void neijie()

{

double e,b=1,d; //b:为正多边形边长

long int i; //i:正多边形边数

for(i=6;;i*=2) //正多边形边数加倍

{

d=1.0-sqrt(1.0-b*b/4); //计算圆内接正多边形的边长

b=sqrt(b*b/4+d*d);

if(2*i*b-i*e <1e-15) //2*i*b迭代后的周长,i*e原来的周长

break; //精度达1e-15则停止计算

e=b; //保存本次正多边形的边长作为下一次精度控制的依据

}

printf( "用圆内接正多边形计算π=%.15lf\n 迭代后得正多边形的边数为:%d\n",i*b,i);

}

void waiqie()

{

double e,b=2*sqrt(3)/3,d; //b:为正多边形边长

long int i; //i:正多边形边数

for(i=6;;i*=2) //正多边形边数加倍

{

相关文档
最新文档