首页 > 代码库 > 求圆周率π的几种方法
求圆周率π的几种方法
方法1:概率法求π的近似值。
概率法又称蒙特卡罗法。假设有一个半径为1的圆,则四分之一圆的面积等于1/4π。通过概率法计算出四分之一圆的面积,也就得到了1/4π。具体过程为:利用随机函数产生横坐标x和纵坐标y(两个值在0~1之间),接着判断由这两个随机数构成的点是否位于1/4圆的区域内,若该点位于1/4圆内则进行计数。由于随机函数生成的点坐标有一定的均匀性,当生成的点足够多时,就可得到阴影内和阴影外点的近似均匀分布。
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int n, sum = 0; double x, y; printf("请输入点的数量:"); scanf("%d", &n); srand((unsigned)time(NULL)); for (int i = 1; i < n; i++) { x = (double)rand() / RAND_MAX; y = (double)rand() / RAND_MAX; if (x * x + y * y <= 1) { sum += 1; } } printf("PI = %f\n", (double)4 * sum / n); return 0; }
方法2:割圆法求π的近似值。
割圆法利用圆的内接多边形来逼近圆的周长。通过不断地将内接多边形进行切割划分,使其无限逼近圆周,则可得到精确度更高的π值。
#include <stdio.h> #include <math.h> int main(void) { double x = 1, PI; int count, n = 0; int s = 6; //初始内接圆边数 printf("请输入割圆次数:"); scanf("%d", &count); while (n <= count) { printf("第%d次割圆,内接正%d边形:", n, s); PI = s * x / 2; printf("PI = %.12f\n", PI); x = sqrt(2 - sqrt(4 - x * x)); s *= 2; n += 1; } return 0; }方法3:公式法求π的近似值。
利用以下公式可方便计算π的近似值。π=2+2/3+2/3×2/5+2/3×2/5×3/7+2/3×2/5×3/7×4/9+?
#include <stdio.h> int main(void) { double temp = 2, PI = 2; int a = 1, b = 3; //a为分子,b为分母 while (temp > 1e-20) { temp *= (double)a / b; PI += temp; a += 1; b += 2; } printf("PI = %.12f\n", PI); return 0; }注意:程序中需要根据精度要求结束循环。
方法4:计算任意位数的π。
方法1至方法3计算出来的π值,由于使用单变量保存结果,限于计算机硬件对变量的表示范围有限,因此,最多只能计算出π值小数点后十多位。为了提高精度,可定义数组来逐位保存无限循环小数,基本思路仍然是利用方法3的公式法。
#include <stdio.h> #include <stdlib.h> int main(void) { char *temp, *pi; int decLen; //小数位数 int a = 1, b = 3; //分子分母 int result, i, carry; int count = 0, flag = 1; //计算次数 printf("请输入π的小数位数:"); scanf("%d", &decLen); decLen += 2; if (!(temp = (char *)malloc(sizeof(char) * decLen))) { return 0; } if (!(pi = (char *)malloc(sizeof(char) * decLen))) { return 0; } for (i = 0; i < decLen; i++) { *(pi + i) = 0; *(temp + i) = 0; } pi[1] = 2; //初始化值 temp[1] = 2; while (flag && ++count < 1e6) { carry = 0; for (i = decLen - 1; i >= 0 ; i--) { result = temp[i] * a + carry; temp[i] = result % 10; carry = result / 10; } carry = 0; for (i = 0; i < decLen; i++) { result = temp[i] + carry * 10; temp[i] = result / b; carry = result % b; } flag = 0; for (i = decLen - 1; i > 0; i--) { result = pi[i] + temp[i]; pi[i] = result % 10; pi[i - 1] += result / 10; flag |= temp[i]; } a += 1; b += 2; } printf("计算了:%d次\n", count); printf("PI = %d.", pi[1]); //输出个位和小数点 for (i = 2; i < decLen; i++) { if ((i > 2) && (i - 2) % 10 == 0) { printf(" "); } if ((i > 2) && (i - 2) % 50 == 0) { printf("\n"); } printf("%d", pi[i]); } printf("\n"); return 0; }
注意:终止循环的条件是:数组temp中全部为0,即已经没有余数需要处理。如果数组中元素一直不为0,则还需要设置另外的条件来终止循环,如规定循环处理次数。
求圆周率π的几种方法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。