Как рассчитывается пи (π)? - PullRequest
34 голосов
/ 16 апреля 2010

Как я могу написать функцию, которая будет возвращать число pi (π) для заданного числа десятичных знаков?

Скорость не имеет значения. Я смотрю на http://bellard.org/pi/,, но до сих пор не понимаю, как получить n-ю цифру числа пи.

Ответы [ 13 ]

30 голосов
/ 16 апреля 2010

В исчислении есть такая вещь, как ряд Тейлора, которая обеспечивает простой способ вычисления многих иррациональных значений с произвольной точностью.

Pi / 4 = 1 - 1/3 + 1/5 - 1/7 + ...
(от http://www.math.hmc.edu/funfacts/ffiles/30001.1-3.shtml)

Продолжайте добавлять эти термины, пока число цифр точности, которое вы хотите стабилизировать.

Теорема Тейлора является мощным инструментом, но вывод этого ряда с использованием теоремы выходит за рамки вопроса. Это стандартное исчисление за первый год обучения, и его можно легко найти, если вас интересует более подробная информация.


Я не хотел сказать, что это самый практичный метод для вычисления числа пи. Это будет зависеть от того, почему вам действительно нужно это сделать. В практических целях вам просто нужно скопировать столько цифр, сколько вам нужно, из одной из многих опубликованных версий. Я предлагал это как простое введение в то, как иррациональные значения могут быть приравнены к бесконечным рядам.

27 голосов
/ 16 апреля 2010

Существует множество алгоритмов для числового приближения π .

12 голосов
/ 16 апреля 2010

Последняя формула: http://en.wikipedia.org/wiki/Bellard%27s_formula

8 голосов
/ 16 апреля 2010

В качестве альтернативы методу хранения каждого варианта Джеффа, вы можете просто сохранить максимальное количество цифр и обрезать то, что вам не нужно:

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

http://codepad.org/6mqDa1zj

6 голосов
/ 20 апреля 2010

Я полагаю, что алгоритм, который вы ищете, называется «алгоритм Spigot». Одним конкретным видом является формула BBP (Бэйли-Борвейн-Плуфф).

Я верю, что это то, что вы ищете.

6 голосов
/ 16 апреля 2010

Попробуйте " Вычисление n-й цифры числа pi в любой базе в O (n ^ 2) ". Вероятно, это самый быстрый известный алгоритм, который не требует произвольных (читай огромная ) значений точности и может дать вам результат непосредственно в базе 10 (или любой другой).

5 голосов
/ 17 апреля 2010

" π в наборе Мандельброта " исследует любопытную взаимосвязь между последовательностью точек на комплексной плоскости и тем, как вычисляется их "число Мандельброта" (из-за отсутствия лучшего термина ... количества итераций требуется, чтобы определить, что точки в последовательности не являются членами набора Мандельброта) относится к PI.

Практическая? Вероятно, нет.

Неожиданно и интересно? Я так думаю.

3 голосов
/ 28 августа 2014

Я бы начал с формулы

pi = 16 arctan (1/5) - 4 arctan (1/239)

Google легко найдет доказательство для этой формулы, которую могут понять нормальные люди, и формулу для вычисления функции арктангенса. Это позволит вам легко и быстро вычислить несколько тысяч десятичных цифр числа Пи.

3 голосов
/ 16 апреля 2010

Готовы ли вы искать значения вместо их вычисления?

Поскольку вы не указали явно, что ваша функция должна вычислять значения, вот возможное решение , если вы хотите иметь верхний предел количества цифр, которые она может "вычислить"

// 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 в пределах вашего верхнего предела.

2 голосов
/ 28 ноября 2018

Мои два цента ... Это может быть не самым быстрым, но я думаю, что это довольно легко понять. Я придумал это сам во время математической лекции, и я действительно не видел это нигде в литературе. Либо я гений, действительно глупый, либо не обращаю внимания на чтение книг по математике, или на все вышеперечисленное ... :)

В любом случае ... Начните с круга единиц. Мы знаем, что x ^ 2 + y ^ 2 = 1, поэтому y = sqrt (1-x ^ 2). Мы также знаем, что площадь единичного круга равна PI. Если мы теперь возьмем интеграл от функции sqrt (1-x ^ 2) в диапазоне от 0 до 1, мы получим четверть PI. Умножьте это на 4, чтобы получить ПИ:

PI formula

Если бы мы попытались решить это аналитически, я уверен, что мы просто вернули бы 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 правильных десятичных знаков. Не самый эффективный, но это мой ребенок ...:)

...