首页 > 技术文章 > 今天是圆周率节,我们一起来用C++来求π吧!

EricNTH 2020-03-14 10:30 原文

 

前言

3.1415926535897932384626433832795…

不好意思,小编我只能被到这里了,当然我觉得做题只要3.14就够了,没必要背那么长的啊。。。当时我上小学时总是和同学们比背π,后来发现也没什么必要哈~当时我们班有能背到100位的,还被我们膜拜了一番(虽然背到30几位我们也不知道他是不是在乱说)。当然了,如果哪位想锻炼以下记忆力的,你尽管背好了。(Haha)因为圆周率是一个无限不循环小数,既没规律又背不完【呜呜】

当时,我们班有好些同学以为圆周率里是没有0的(前二三十位确实没有),后来大家才知道。。。我能背完的那些后面省略号的第一位就是0。。。【偷笑】


本文为EricNTH的原创博客,转载请注明出处!

欢迎关注我的公众号:Huayu_IT!里面有许多编程和计算机的有趣知识哦~


 

 


言归正传

好,我们开始吧。先从圆周率的定义说起吧~

圆周率(Pi)是圆的周长与直径的比值,一般用希腊字母π表示,是一个在数学及物理学中普遍存在的数学常数。π也等于圆形之面积与半径平方之比,是精确计算圆周长、圆面积、球体积等几何形状的关键值。在分析学里,π可以严格地定义为满足sinx=0的最小正实数x。
——From: baike.baidu.com

我不想让这篇文章变得枯燥,当然我相信圆周率的定义没人不知道(幼儿园小朋友们除外),所以就不过多讲述了哟~

π的历史

π的历史太久远了,我们远的不说,还是先来弘扬一下爱国主义精神吧~

中国古算书《周髀算经》的中有“径一而周三”的记载,就是指π取3。汉朝时,张衡算出π约为10的平方根3.162。这个值不太准确,但它简单易理解,容易记。别着急,厉害的在后面呢!

公元263年,三国时代魏国数学家刘徽用“割圆术”计算圆周率,他先从圆内接正六边形,逐次分割一直算到圆内接正192边形。“割之弥细,所失弥少,割之又割,以至于不可割,则与圆周合体而无所失矣。”(这句话很有名哦)。
这句话我们现在都能理解,但在当时可谓十分先进了。它包含了极限的思想。刘徽在得圆周率=3.14之后,将这个数值和当时的模型相比 ,发现3.14这个数值还是偏小。于是继续割圆到1536边形,求出3072边形的面积,得到令自己满意的圆周率:π约等于3.1416。(完全正确!4位了)

公元480年左右,南北朝时期的数学家祖冲之进一步得出精确到小数点后7位的结果,给出近似值3.1415926~3.1415927(哇!还是完全正确!7位了!),还得到两个近似分数值,密率355/113(3.14159292)和疏率22/7(3.14285714)。密率是个很好的分数近似值哦,简单易记又精确,想要再精确一点点,分子和分母就要上5位,谁记得住啊!看来,祖冲之对圆周率也是功不可没啊!

好了,接下来的一千年中,没有更精确的了~(太牛了!)

之后,阿拉伯数学家卡西在15世纪初求得圆周率17位精确小数值,打破祖冲之保持近千年的纪录。(还是亚洲人聪明)

德国数学家鲁道夫耗尽毕生心血于1610年算到小数后35位数,该数值被用他的名字称为鲁道夫数。(德国人严谨啊~)

后来人们开始利用无穷级数或无穷连乘(看到没,都和无穷有关,还是刘徽牛啊)积求π,摆脱可割圆术的繁复计算。各种π值表达式纷纷出现,使得π值计算精度迅速增加。

第一个快速算法由英国数学家梅钦(John Machin)提出,1706年梅钦计算π值突破100位小数大关,他利用了如下公式:

到1948年英国的弗格森和美国的伦奇共同发表了π的808位小数值,成为人工计算圆周率值的最高纪录。


还是计算机靠得住啊!
自从电子计算机发展以来,π的精度不断增加~

。。。此处省略1万字。。。

2011年10月16日,日本长野县饭田市公司职员近藤茂利用家中电脑将圆周率计算到小数点后10万亿位,刷新了2010年8月由他自己创下的5万亿位吉尼斯世界纪录。花费约一年时间。(用的只是家里自己装的电脑哦,我也不知道那么久没关机怎么搞的)


好了,你想不想学一学前辈,用自己家的电脑算一算圆周率呢?


用C++来算π

你不可能用电脑画一个圆,然后连出它的直径,然后让电脑帮你除一除吧?

方法1

我们还是需要公式。

#include <bits/stdc++.h>
using namespace std;

int main(){
    short s=1;
    float pi=0;
    float i=1.0;
    float n=1.0;
    while(fabs(i)>=1e-6/){//即i不等于0,浮点数很多时候都需要这样做。因为它使用的是科学计数法,多少也有点误差。直接i!=0会出错
        pi+=i;
        n=n+2;
        s=-s; 
        i=s*1.0/n;
    }
    pi=4*pi;
    printf("PI = %.6f\n",pi);
    
    return 0;
}

它用的公式是:

我们要的还是准确性啊,那我们来看看结果如何?

输出:PI = 3.141594
不错,如果你把精度调大一点,相信你也可以求到一万位!


不过,这样似乎又有点太做作了,
于是就有了——

方法2

反正你也可以背到二三十位嘛,那你为什么不定一个宏呢?
(不要脸中。。。)
不过不用劳烦您大驾了,<cmath>头文件中已经帮你定义好了~

#define M_PI       3.14159265358979323846
#define M_PI_2     1.57079632679489661923
#define M_PI_4     0.785398163397448309616

当然,另一个无理数e,也有…

#define M_E        2.71828182845904523536
#define M_LOG2E    1.44269504088896340736
#define M_LOG10E   0.434294481903251827651

反正你实际用的时候M_PI就足够了,就不用自己求了(哈)

好了,就讲这些吧~

大家不要忘了,在3月14日15点9分26秒,捧上一个香喷喷的Pie,享用哦~
(麦当劳的派可能要被买爆了)

最后,祝大家圆周率节快乐~


本文为EricNTH的原创博客,转载请注明出处!


Bye!

 

推荐阅读