【基础算法】圆周率的多种方法求算 & 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月前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
162 4
|
3月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
73 3
|
17天前
|
机器学习/深度学习 人工智能 算法
机器学习算法的优化与改进:提升模型性能的策略与方法
机器学习算法的优化与改进:提升模型性能的策略与方法
125 13
机器学习算法的优化与改进:提升模型性能的策略与方法
|
12天前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
36 2
|
20天前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
18天前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
2月前
|
存储 算法 安全
SnowflakeIdGenerator-雪花算法id生成方法
SnowflakeIdGenerator-雪花算法id生成方法
42 1
|
2月前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
125 0
|
3月前
|
算法 索引
HashMap扩容时的rehash方法中(e.hash & oldCap) == 0算法推导
HashMap在扩容时,会创建一个新数组,并将旧数组中的数据迁移过去。通过(e.hash & oldCap)是否等于0,数据被巧妙地分为两类:一类保持原有索引位置,另一类索引位置增加旧数组长度。此过程确保了数据均匀分布,提高了查询效率。
63 2
|
3月前
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
979 0
高精度算法(加、减、乘、除,使用c++实现)