割圆法
一个圆如下面左图所示,其半径为1,其内部内接一个正六边形。设正六边形的边长为y1。由几何知识可得知y1=1,所以圆的周长可近似为正六边形的周长C=6×y1=6.所以圆周率为前面的近似圆周长与圆直径之比,即C/2= 3≈π,这就是按照割圆法来得到圆周率近似值的方法。
分析:(上面右图所示)
其中边长为m、y1、y2的三条边构成一个小直角三角形,根据勾股定理可得:
其中边长为n,y1,1的三条边构成一个较大的三角形,根据勾股定理可得:
结合条件图中已知条件(m+n=1)和几何关系对公式继续进行化简推导:
所以圆周率π的近似值为:
如果内接24边形,其边长为y3,则其圆周率为:
如果内接48边形,其边长为y4,则其圆周率为:
……
综上归纳可知,在割圆术这个算法中主要用到以下两个公式:
#include<iostream> #include<cmath> #include<iomanip> using namespace std; class cyclotomic { public: void cyclotomic1() { int i = 1,a=1; double len = 1; while(i<=n) { len = 2 - sqrt(4 - len); //内接多边形的边长 a *= 2; i++; } pi = 3.0 * (double)a * sqrt(len); } void showresult() { cout.precision(12); //小数点后第十二位 cout << pi << endl; } int n; double pi; }; void text() { cyclotomic c; cout << "输入要切割的次数:" << endl; cin>>c.n; c.cyclotomic1(); c.showresult(); } int main() { text(); }
●级数公式法
在微积分中,对一个表达式进行级数展开并取极限便可以得到一系列的迭代计算公式。对于圆周率π也可以采用相同的方法来得到级数公式(泰勒展开式)。这样的级数公式很多,依赖于不同的级数展开表达式,下面就是一个典型的求圆周率级数公式的例子:
#include<iostream> #include<iomanip> using namespace std; class series1 { public: void series_1() { int i = 1; double sum=1,record=1, m=1, n=3,t; while (i <= x) { t = m / n; t = t * record; sum += t; m += 1; n += 2; record = t; i++; } pi = 2.0 * sum; } void showresult() { cout.precision(12);//小数点后第十二位 cout << pi << endl; } int x; double pi; }; void text() { series1 s1; cout << "请输入该公式往后计算的位数:" << endl; cin >> s1.x; s1.series_1(); s1.showresult(); } int main() { text(); }
●格雷戈里公式法
格雷戈里公式的实质是反正切函数的泰勒展开式,属于级数公式的一种,具体公式如下:
#include<iostream> #include<iomanip> #include<cmath> using namespace std; class Gregory { public: void Gregory1() { int sign = 1; double m = 1, term = 1; while (fabs(term) >= x) { pi += term; m += 2; sign = -sign; term = sign / m; } pi = 4.0 * pi; } void showresult() { cout.precision(12);//小数点后第十二位 cout << pi << endl; } double x; double pi=0; }; void text() { Gregory g; cout << "输入精度e的值:" <<endl; cin >> g.x; g.Gregory1(); g.showresult(); } int main() { text(); }
●蒙特卡洛
在概率算法的文章中,举的蒙特卡洛算法例子就是用概率的方法去寻找π,具体在http://t.csdn.cn/VifFM