码迷,mamicode.com
首页 > 其他好文 > 详细

求圆周率π的几种方法

时间:2014-12-03 20:57:11      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   使用   sp   for   strong   

方法1:概率法求π的近似值。

概率法又称蒙特卡罗法。假设有一个半径为1的圆,则四分之一圆的面积等于1/4π。通过概率法计算出四分之一圆的面积,也就得到了1/4π。具体过程为:利用随机函数产生横坐标x和纵坐标y(两个值在0~1之间),接着判断由这两个随机数构成的点是否位于1/4圆的区域内,若该点位于1/4圆内则进行计数。由于随机函数生成的点坐标有一定的均匀性,当生成的点足够多时,就可得到阴影内和阴影外点的近似均匀分布。

 1 #include <stdio.h>  
 2 #include <stdlib.h>  
 3 #include <time.h>  
 4   
 5 int main(void)  
 6 {  
 7     int n, sum = 0;  
 8     double x, y;  
 9     printf("请输入点的数量:");  
10     scanf("%d", &n);  
11     srand((unsigned)time(NULL));  
12     for (int i = 1; i < n; i++)  
13     {  
14         x = (double)rand() / RAND_MAX;  
15         y = (double)rand() / RAND_MAX;  
16         if (x * x + y * y <= 1)  
17         {  
18             sum += 1;  
19         }  
20     }  
21     printf("PI = %f\n", (double)4 * sum / n);  
22       
23     return 0;  
24 }  

 

方法2:割圆法求π的近似值。

割圆法利用圆的内接多边形来逼近圆的周长。通过不断地将内接多边形进行切割划分,使其无限逼近圆周,则可得到精确度更高的π值。

 1 #include <stdio.h>  
 2 #include <math.h>  
 3   
 4 int main(void)  
 5 {  
 6     double x = 1, PI;  
 7     int count, n = 0;  
 8     int s = 6;                  //初始内接圆边数  
 9     printf("请输入割圆次数:");  
10     scanf("%d", &count);  
11       
12     while (n <= count)  
13     {  
14         printf("第%d次割圆,内接正%d边形:", n, s);  
15         PI = s * x / 2;  
16         printf("PI = %.12f\n", PI);  
17         x = sqrt(2 - sqrt(4 - x * x));  
18         s *= 2;  
19         n += 1;  
20     }  
21       
22     return 0;  
23 }  

 

方法3:公式法求π的近似值。

利用以下公式可方便计算π的近似值。π=2+2/3+2/3×2/5+2/3×2/5×3/7+2/3×2/5×3/7×4/9+?

 1 #include <stdio.h>  
 2   
 3 int main(void)  
 4 {  
 5     double temp = 2, PI = 2;  
 6     int a = 1, b = 3;       //a为分子,b为分母  
 7   
 8     while (temp > 1e-20)  
 9     {  
10         temp *= (double)a / b;  
11         PI += temp;  
12         a += 1;  
13         b += 2;  
14     }  
15     printf("PI = %.12f\n", PI);  
16   
17     return 0;  
18 }  

注意:程序中需要根据精度要求结束循环。

 

方法4:计算任意位数的π。

方法1至方法3计算出来的π值,由于使用单变量保存结果,限于计算机硬件对变量的表示范围有限,因此,最多只能计算出π值小数点后十多位。为了提高精度,可定义数组来逐位保存无限循环小数,基本思路仍然是利用方法3的公式法。

 1 #include <stdio.h>  
 2 #include <stdlib.h>  
 3   
 4 int main(void)  
 5 {  
 6     char *temp, *pi;  
 7     int decLen;                 //小数位数  
 8     int a = 1, b = 3;           //分子分母  
 9     int result, i, carry;  
10     int count = 0, flag = 1;    //计算次数  
11       
12     printf("请输入π的小数位数:");  
13     scanf("%d", &decLen);  
14     decLen += 2;  
15   
16     if (!(temp = (char *)malloc(sizeof(char) * decLen)))  
17     {  
18         return 0;  
19     }  
20     if (!(pi = (char *)malloc(sizeof(char) * decLen)))  
21     {  
22         return 0;  
23     }  
24   
25     for (i = 0; i < decLen; i++)  
26     {  
27         *(pi + i) = 0;  
28         *(temp + i) = 0;  
29     }  
30   
31     pi[1] = 2;                      //初始化值  
32     temp[1] = 2;  
33       
34     while (flag && ++count < 1e6)  
35     {  
36         carry = 0;  
37         for (i = decLen - 1; i >= 0 ; i--)  
38         {  
39             result = temp[i] * a + carry;  
40             temp[i] = result % 10;  
41             carry = result / 10;  
42         }  
43           
44         carry = 0;  
45         for (i = 0; i < decLen; i++)  
46         {  
47             result = temp[i] + carry * 10;  
48             temp[i] = result / b;  
49             carry = result % b;  
50         }  
51           
52         flag = 0;  
53         for (i = decLen - 1; i > 0; i--)  
54         {  
55             result = pi[i] + temp[i];  
56             pi[i] = result % 10;  
57             pi[i - 1] += result / 10;  
58             flag |= temp[i];  
59         }  
60   
61         a += 1;  
62         b += 2;  
63     }  
64   
65     printf("计算了:%d次\n", count);  
66     printf("PI = %d.", pi[1]);      //输出个位和小数点  
67     for (i = 2; i < decLen; i++)  
68     {  
69         if ((i > 2) && (i - 2) % 10 == 0)  
70         {  
71             printf(" ");  
72         }  
73         if ((i > 2) && (i - 2) % 50 == 0)  
74         {  
75             printf("\n");  
76         }  
77   
78         printf("%d", pi[i]);  
79     }  
80     printf("\n");  
81   
82     return 0;  
83 }  

注意:终止循环的条件是:数组temp中全部为0,即已经没有余数需要处理。如果数组中元素一直不为0,则还需要设置另外的条件来终止循环,如规定循环处理次数。

求圆周率π的几种方法

标签:style   blog   io   ar   color   使用   sp   for   strong   

原文地址:http://www.cnblogs.com/mengwang024/p/4140968.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!