π是是指圆的周长与直径的比值,是无限不循环小数,有很多种方法可以求得它的近似值。这里用比较容易实现的关于π的无穷级数来求它的前10000位的取值。
π / 2 =
π =
具体的,用两个字符数组x,z分别存放当前计算得到的pi值,数组的每一位存放一位数字,然后设定循环,从左向右分别计算pi级数中的每一项。数组z负责计算级数的当前项,计算过程参见代码注释:
//头文件
#ifndef CALCPI_H_
#define CALCPI_H_
#include <cstring>
#include <iostream>
const int ARRSIZE = 10100, DISCNT = 10000; //定义数组大小和显示位数
void calcPi();
#endif // !CALCPI_H_
#include "calcPi.h"
//pi级数 pi = 2 + 2 / 3 + 2 / 3 * 3 / 5 +......
void calcPi() {
char x[ARRSIZE], z[ARRSIZE];
int a = 1, b = 3, cnt = 0,RUN = 1;
memset(x, '0', ARRSIZE);
memset(z, '0', ARRSIZE);
x[0] = '2', //pi级数的第一项 2
z[0] = '2'; //2倍
while (RUN && cnt < ARRSIZE * 10) {
//z * = a;
int c = 0;
int d = 0; //d是进位 数组从右向左模拟Pi级数的乘法运算
for (int i = ARRSIZE - 1; i >= 0; i--) {
c = (z[i] - '0') * a + d;
z[i] = (c % 10) + '0';
d = c / 10;
// std::cout << z[i] - '0' <<" ";
// break;
}
// z /= b
d = 0; //d是余数传导到下一位数字,数组从左向右模拟pi级数的除法运算
for (int i = 0; i < ARRSIZE; i++) {
c = (z[i] - '0') + d * 10;
z[i] = (c / b) + '0';
d = c % b; //余数
}
//x += z; 将pi级数分开计算的各个项相加得到Pi
RUN = 0;
for (int i = ARRSIZE - 1; i > 0; i--) {
c = (x[i] - '0') + (z[i] - '0');
x[i] = (c % 10) + '0';
x[i - 1] = x[i - 1] + c / 10; //进位直接加到下一位数字上
RUN |= (z[i] - '0'); //判断级数是否已经收敛,即当前项所得的结果前ARRSIZE项都为0,达到所需要精度退出循环
}
a++;
b += 2;
cnt++;
std::cout << cnt << " ";
}
for (int i = 0; i <= DISCNT; i++) {
if (0 == i)std::cout << x[i] << '.';
else std::cout << x[i];
}
//std::cout << std::endl;
//std::cout <<"总计计算次数: "<<cnt<<std::endl;
}
参考链接: 计算圆周率 Pi (π) 值, 精确到小数点后 10000 位