如何编写一个函数,以给定的小数位数返回圆周率(π)?
速度不是问题。我一直在查看http://bellard.org/pi/,但我仍然不明白如何获取π的第n位数字。
如何编写一个函数,以给定的小数位数返回圆周率(π)?
速度不是问题。我一直在查看http://bellard.org/pi/,但我仍然不明白如何获取π的第n位数字。
在微积分中,有一个叫做泰勒级数的东西,可以提供一种简单的方法来计算许多无理数到任意精度。
π/4 = 1 - 1/3 + 1/5 - 1/7 + ...
(来源:http://www.math.hmc.edu/funfacts/ffiles/30001.1-3.shtml)
继续添加这些项,直到您想要的精度位数稳定为止。
泰勒定理是一个强大的工具,但使用该定理导出该级数超出了问题的范围。如果您对更多细节感兴趣,它是标准的大学第一年微积分知识,并且可以轻松通过谷歌搜索获得。
我并不是想暗示这是计算π最实用的方法。那将取决于您真正需要计算π的原因。为实际目的,您应该直接从已经发布的版本中复制所需数量的数字。我之所以建议这么做,是为了简单介绍如何将无理数等同于无限级数。
#include <string>
#include <iostream>
using std::cout; using std::endl; using std::string;
// The first 99 decimal digits taken from:
// http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
// Add more as needed.
const string pi =
"1415926535"
"8979323846"
"2643383279"
"5028841971"
"6939937510"
"5820974944"
"5923078164"
"0628620899"
"8628034825"
"342117067";
// A function in C++ that returns pi to X places
string CalcPi(const size_t decimalDigitsCount)
{
string returnValue = "3";
if (decimalDigitsCount > 0)
{
returnValue += "." + pi.substr(0, decimalDigitsCount);
}
return returnValue;
}
int main()
{
// Loop through all the values of "pi at x digits" that we have.
for (size_t i = 0; i <= pi.size(); ++i)
{
cout << "pi(" << i << "): " << CalcPi(i) << endl;
}
}
我会从公式入手
pi = 16 arctan (1/5) - 4 arctan (1/239)
谷歌可以轻松地找到一个普通人能够理解的这个公式的证明,以及计算反正切函数的公式。这将使您能够轻松快速地计算几千个小数位的圆周率。
由于您没有明确指定函数必须计算值,因此如果您愿意对可以“计算”的数字数量设定上限,则以下是可能的解决方案:
// Initialize pis as far out as you want.
// There are lots of places you can look up pi out to a specific # of digits.
double pis[] = {3.0, 3.1, 3.14, 3.141, 3.1416};
/*
* A function that returns pi out to a number of digits (up to a point)
*/
double CalcPi(int x)
{
// NOTE: Should add range checking here. For now, do not access past end of pis[]
return pis[x];
}
int main()
{
// Loop through all the values of "pi at x digits" that we have.
for (int ii=0; ii<(int)sizeof(pis)/sizeof(double); ii++)
{
double piAtXdigits = CalcPi(ii);
}
}
无论如何...从单位圆开始。我们知道x ^ 2 + y ^ 2 = 1,因此y = sqrt(1-x ^ 2)。我们还知道单位圆的面积是PI。如果我们现在在范围0到1内对函数sqrt(1-x ^ 2)进行积分,我们将得到PI的四分之一。因此,将其乘以4即可得到PI:
如果我们试图从分析角度解决这个问题,我相信我们只会得到圆周率。但是编写一个数值求解程序却非常容易。以下是一个用C语言编写的程序:#include <math.h>
#include <stdio.h>
void main(void) {
double interval=0.0000001,area=0,x,y;
for (x=0; x<1; x+=interval)
area+=4*interval*sqrt(1-x*x);
printf("pi ~ %.20f\n",area);
}
pi ~ 3.14159285415672595576
pi = function () {
let pi = 3;
let a = 3;
let even = false;
let turn;
while (a <= 90000) {
turn = (4/((Math.pow(a, 3)) - (a)));
if(even){
turn = turn*-1;
even = false;
} else {
even = true;
}
pi = pi + turn;
a = a + 2;
}
return pi;
};
PI
。以下是它的C++实现代码。#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
long double calPI(long iterations = 1000)
{
long double pi = 0.0, factor = 1;
long i;
for (i = 2; i < iterations; i += 2, factor *= -1)
{
pi += factor / (i - 1.0);
}
return 4 * pi;
}
// 3.14159265358979323846264338327950288419716939937510 -> Actual (50 digits)
// 3.141592653589793115997963468544185161590576171875 -> From acos
// 3.14159265452113118342880593303334535448811948299407958984375 -> Calculated
int main()
{
int digits;
long double PI;
cout << "Enter how many digits of precision you want to have : ";
cin >> digits;
PI = calPI(2147453647); // By far the maximum precision I was able to reach
cout << "The value of pi upto " << digits << " digits : " << setprecision(digits) << PI << endl;
cout << "Actual value of pi from math.h : " << 2 * acos(0.0) << endl;
return 0;
}
实际上,关于我使用的这个序列是如何推导出来的,这里有一个非常好的解释,我强烈建议你观看。