首页 > 代码库 > 求圆周率π的几种方法
求圆周率π的几种方法
方法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,则还需要设置另外的条件来终止循环,如规定循环处理次数。
求圆周率π的几种方法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。