首页 > 代码库 > 求圆周率π的几种方法

求圆周率π的几种方法

方法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,则还需要设置另外的条件来终止循环,如规定循环处理次数。

求圆周率π的几种方法