【基础算法】圆周率的多种方法求算 & C++实现

简介: 一个圆如下面左图所示,其半径为1,其内部内接一个正六边形。设正六边形的边长为y1。由几何知识可得知y1=1,所以圆的周长可近似为正六边形的周长C=6×y1=6.所以圆周率为前面的近似圆周长与圆直径之比,即C/2= 3≈π,这就是按照割圆法来得到圆周率近似值的方法。

割圆法


       一个圆如下面左图所示,其半径为1,其内部内接一个正六边形。设正六边形的边长为y1。由几何知识可得知y1=1,所以圆的周长可近似为正六边形的周长C=6×y1=6.所以圆周率为前面的近似圆周长与圆直径之比,即C/2= 3≈π,这就是按照割圆法来得到圆周率近似值的方法。

44f2dc372a0653e98cf97c8a2a561910_beacb1eb43f84150b1ae6f902b4f1eaa.png


分析:(上面右图所示)


其中边长为m、y1、y2的三条边构成一个小直角三角形,根据勾股定理可得:

e8f47f7a8e8cebe093b7476575fb6caf_f7aeee6bd93a4fe1adc4dd9ad0a54f33.png

其中边长为n,y1,1的三条边构成一个较大的三角形,根据勾股定理可得:

e743cf7f5dabcde54406b677e9924140_77c6206857b4465f9e8689e946609187.png

结合条件图中已知条件(m+n=1)和几何关系对公式继续进行化简推导:

0d57ea096ade10876552273249d07be1_63bbc6d1bfa9440aaedd7e24f34d08df.png

所以圆周率π的近似值为:

91b58ba88e40563855ddce28ee00d7cf_5b0a7c5d763a4c769e4e5dd47defb9b7.png

如果内接24边形,其边长为y3,则其圆周率为:

dfe1a6a0bb8bd7c4ed9c5c055196b645_538746e2ee2d4dc7916eccd82c441982.png

如果内接48边形,其边长为y4,则其圆周率为:

d7b2b0d3fb451d05fe333f03859a3c63_dd851708b8fa4a33ba1dae8fb65e641c.png

……


综上归纳可知,在割圆术这个算法中主要用到以下两个公式:

7d2589ff462843fefe55a37064443739_ca21c3301e844760b4c680f04bf3325f.png

#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();
}

cb98cecf344f590c5a9463b8e99d1e20_be8e316b599a4f0ba5f4af0a2537c3af.png


●级数公式法


       在微积分中,对一个表达式进行级数展开并取极限便可以得到一系列的迭代计算公式。对于圆周率π也可以采用相同的方法来得到级数公式(泰勒展开式)。这样的级数公式很多,依赖于不同的级数展开表达式,下面就是一个典型的求圆周率级数公式的例子:

719cec5ac1c321ae59b447f55b05ea02_e95f95de906d405e9477f358aa92dca0.png

c12d0e7692a9ed5cb291a3adadfd1907_b26273be30354e5b85a71c9add462eb0.png

#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();
}

13aed22994c3f3a3d443dae9815bce5a_187b1a10f6204b14b8894ad2e2066967.png

●格雷戈里公式法


       格雷戈里公式的实质是反正切函数的泰勒展开式,属于级数公式的一种,具体公式如下:

db2af17fc1173062995ff1e8c70be997_6a93e135c7e642ce8de179a6339749de.png


0c73c17261a740f56c2e14793f302263_2d74b3ac110d429d9bfb71d5891287b6.png

#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();
}

816e0706e90bc0b802069e7387f7c2fb_8c61c961071c41e891dc588fd5551578.png

●蒙特卡洛


       在概率算法的文章中,举的蒙特卡洛算法例子就是用概率的方法去寻找π,具体在http://t.csdn.cn/VifFM


目录
相关文章
|
2月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
45 3
|
2月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
2月前
|
算法 索引
HashMap扩容时的rehash方法中(e.hash & oldCap) == 0算法推导
HashMap在扩容时,会创建一个新数组,并将旧数组中的数据迁移过去。通过(e.hash & oldCap)是否等于0,数据被巧妙地分为两类:一类保持原有索引位置,另一类索引位置增加旧数组长度。此过程确保了数据均匀分布,提高了查询效率。
39 2
|
2月前
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
508 0
高精度算法(加、减、乘、除,使用c++实现)
|
2月前
|
存储 算法 Java
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
前缀(波兰)表达式、中缀表达式和后缀(逆波兰)表达式的基本概念、计算机求值方法,以及如何将中缀表达式转换为后缀表达式,并提供了相应的Java代码实现和测试结果。
70 0
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
|
2月前
|
存储 算法 决策智能
【算法】博弈论(C/C++)
【算法】博弈论(C/C++)
|
2月前
|
存储 算法 C++
【算法】哈希映射(C/C++)
【算法】哈希映射(C/C++)
|
2月前
|
机器学习/深度学习 人工智能 算法
【算法】最长公共子序列(C/C++)
【算法】最长公共子序列(C/C++)
|
2月前
|
人工智能 算法 BI
一篇带你速通差分算法(C/C++)
一篇带你速通差分算法(C/C++)
|
2月前
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)