如何编写一个将pi(π)返回到给定小数位数的函数?
速度不是问题。我一直在看http://bellard.org/pi/,但我仍然不明白如何获得pi的第n位数。
答案 0 :(得分:29)
在微积分中有一个名为泰勒级数的东西,它提供了一种简单的方法来计算许多无理值到任意精度。
Pi / 4 = 1 - 1/3 + 1/5 - 1/7 + ...
(来自http://www.math.hmc.edu/funfacts/ffiles/30001.1-3.shtml)
继续添加这些术语,直到您希望稳定的精确位数。
泰勒定理是一个强大的工具,但使用该定理推导出这一系列超出了问题的范围。如果您对更多细节感兴趣,那么它是标准的大学一年级微积分,并且很容易转换。
我并不是说暗示这是计算pi的最实用的方法。这取决于你真正需要这样做的原因。出于实际目的,您应该从许多已发布版本中的一个中复制所需数量的数字。我建议将其简单地介绍非理性值如何等同于无限级数。
答案 1 :(得分:26)
答案 2 :(得分:11)
答案 3 :(得分:7)
作为JeffH存储每个变体的方法的替代方法,您只需存储最大位数并切断不需要的数字:
#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;
}
}
答案 4 :(得分:5)
尝试“Computation of the n'th digit of pi in any base in O(n^2)”。它可能是最快的已知算法,不需要任意(读取巨大的)精度浮点数,并且可以直接在基数10(或任何其他)中提供结果。
答案 5 :(得分:5)
我相信您正在寻找的算法就是所谓的“Spigot算法”。一种特殊的是BBP(Bailey-Borwein-Plouffe)公式。
我相信这就是你要找的东西。
答案 6 :(得分:4)
“π IN THE MANDELBROT SET”探讨了复杂平面上一系列点之间的奇妙关系以及如何计算它们的“Mandelbrot数”(因为缺少一个更好的术语......确定点数所需的迭代次数)在序列中不是Mandelbrot集的成员)与PI有关。
实践?可能不是。
出乎意料又有趣?我想是的。
答案 7 :(得分:2)
您可以根据您添加(或减去)的最后一个术语来判断精度。由于艾伦序列中每个项的幅度总是在减小,并且每个项在符号中交替出现,因此总和的变化不会超过上一个项。
翻译那个bab ::添加1/5后,总和的变化不会超过1/5,因此精确到1/5以内。当然,你必须将它乘以4,所以你真的只精确到4/5。
不幸的是,数学并不总是很容易转换为十进制数字。
答案 8 :(得分:2)
由于您没有明确指定您的函数必须计算值,如果您愿意为其计算的位数有一个上限,这里有一个可能的解决方案 “:
// 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);
}
}
以这种方式编写CalcPi()(如果它符合您的需要)有一个附带好处,就是在上限内对任何X值快速同等地尖叫。
答案 9 :(得分:2)
我从公式
开始pi = 16 arctan (1/5) - 4 arctan (1/239)
谷歌很容易找到正常人可以理解的这个公式的证明,以及计算反正切函数的公式。这将允许您非常容易和快速地计算pi的几千个十进制数字。
答案 10 :(得分:2)
我的2美分...这可能不是最快的,但我认为这很容易理解。我在一次数学讲座中自己想到了它,而在文学中没有真正见过它。我要么是个天才,要么很愚蠢,要么不真正关注阅读有关数学的书籍,或者是以上所有...:)
无论如何...从单位圆开始。我们知道x ^ 2 + y ^ 2 = 1,所以y = sqrt(1-x ^ 2)。我们也知道单位圆的面积是PI。如果现在将函数sqrt(1-x ^ 2)的整数取为0到1,我们将得到四分之一的PI。因此,将其乘以4得到PI:
如果我们尝试分析地解决这一问题,我相信我们只会收回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);
}
使用上述interval
的设置运行它,我们得到:
pi ~ 3.14159285415672595576
因此10,000,000次迭代给出6个正确的小数。不是最有效的,但这是我的宝贝...:)
答案 11 :(得分:0)
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;
};
答案 12 :(得分:0)
import math
def pi(x):
for i in range(1,x):
print( (360.0*math.tan(math.radians(1/(2*i))))/(1/i))
这就像获得尽可能小的结果,然后我使用该角度来计算否。的侧面。
边的长度是使用三角函数计算的,然后...您也可以将math.tan
替换为math.sin
。
答案 13 :(得分:-4)
考虑这是一个粗略的草图,但这是一个初学者可以实现的直接方法。
int x = 9;
double pi = double(22/7);
String piAsString = pi.toString();
String valueAtXPosition = piAsString.subString(x, x+1);
int valueAtXPosAsInt = Integer.parseInt(valueAtXPosition);