Cómo calcular el valor de ‘pi’ en mi computadora a través de un programa simple

Gracias por el A2A.

Las otras respuestas en esta página proporcionan métodos válidos para calcular PI. Los únicos comentarios que agregaría son:

1) Los métodos de Monte Carlo (mencionados por Tushar Makkar) son un tema muy interesante y son aplicables para una variedad de problemas (ver, por ejemplo, la integración de Monte Carlo, de los cuales el método de Monte Carlo para aproximar PI es un caso especial). Sin embargo, el método Monte Carlo no es adecuado para generar valores precisos de PI a billones de dígitos (o incluso unos pocos miles de dígitos) como se hizo en la pregunta.

2) Otro problema fundamental (mencionado por Prashant Serai) es que los tipos de datos float y double y otros tipos de datos convencionales no tienen la precisión que necesita. El tipo de datos float (32 bits) solo es preciso para hasta 6-9 dígitos en la parte fraccionaria (y ni siquiera eso para algunos números), y el double solo es preciso para hasta 15-17 dígitos.

En su lugar, necesitaría usar una biblioteca que implemente un tipo de datos de “gran número”, o codificar uno usted mismo. Por ejemplo, vea The GNU MP Bignum Library. Y creo que incluso GMP tendría problemas para ir a billones de dígitos, creo que no admite el uso de operandos en el disco, pero GMP podría manejar algunos miles de millones de dígitos.

3) Para calcular billones de dígitos de PI en una computadora hogareña, necesitaría tener un algoritmo muy eficiente y la implementación más eficiente. Esto seguramente significará la codificación usando C o C ++, y tal vez incluso usando algún lenguaje ensamblador para aprovechar las instrucciones más recientes compatibles con su procesador.

Una implementación razonablemente simple utilizando la fórmula de Machin (un refinamiento del enfoque [matemático] \ frac {\ pi} {4} = tan ^ {- 1} (1) [/ matemático]) que se utilizó para calcular hasta un millón de dígitos de PI se encuentra en Codeproject – Calcule pi a un millón de decimales.

Indudablemente existen mejores enfoques utilizando métodos aún más sofisticados. Un ejemplo que usa la biblioteca GMP se encuentra en la página de cómputo GMP Pi, que usa el algoritmo Chudnovsky (que se usó para los billones de cálculos de dígitos mencionados en la pregunta).

Aproximación numérica de π:

Como los puntos se dispersan aleatoriamente dentro del cuadrado de la unidad, algunos caen dentro del círculo de la unidad. La fracción de puntos dentro del círculo se aproxima a π / 4 a medida que se agregan puntos. π / 4 = m / n, aquí, m es el número de puntos que satisfacen & n es el número de puntos de tamaño de muestra

Método de Monte Carlo aplicado para aproximar el valor de π. Después de colocar 30000 puntos aleatorios, la estimación para π está dentro del 0.07% del valor real.

Para más consulta vaya a este enlace:

Cálculo de Pi utilizando el método de Monte Carlo

Cálculo de Pi con el método de Monte Carlo

Hay un número innumerable de métodos numéricos para calcular el valor de PI, y no solo se han calculado 2,7 billones, sino que de hecho se han calculado 12,1 dígitos de PI hasta ahora utilizando este programa.

Sin embargo, a pesar de que uno puede escribir un programa simple para calcular el valor de PI como uno interesante proporcionado por Tushar Makkar, es probable que surja complejidad cuando desee usar una computadora en el hogar, calcular billones de dígitos y en un tiempo razonable. Las causas de la complejidad pueden ser las siguientes:
1. No puede utilizar los tipos de datos Double / Float incorporados, debido a la precisión muy limitada que proporcionan.
2. Además de un algoritmo eficiente, necesita una implementación óptima, para hacer un gran uso del hardware limitado disponible.
3. Esto está relacionado con (2), pero necesitaría tener una implementación de subprocesos múltiples para hacer el mejor uso de una CPU de múltiples núcleos.

Para empezar, esta página proporciona algunas implementaciones de referencia para la parte de las matemáticas utilizadas por Fabrice Bellard. Tal vez podría llegar a una fórmula significativamente mejor o una mejora de las fórmulas existentes, además de una implementación muy sólida.

Buena suerte.

Podemos calcular el valor de [math] \ pi [/ math] usando el método Monte Carlo.

El “Método Monte Carlo” es un método para resolver problemas utilizando estadísticas. Dada la probabilidad, P, de que ocurra un evento en ciertas condiciones, se puede usar una computadora para generar esas condiciones repetidamente. El número de veces que ocurre el evento dividido por el número de veces que se generan las condiciones debe ser aproximadamente igual a P.


Explicacion:
Si se inscribe un círculo de radio R dentro de un cuadrado con una longitud lateral de 2 * R , entonces el área del círculo será [matemática] \ pi * R ^ 2 [/ matemática] y el área del cuadrado será [matemática] 2 * R ^ 2 [/ matemáticas]. Entonces, la razón del área del círculo al área del cuadrado será pi / 4 .

Esto significa que, si elige N puntos al azar dentro del cuadrado, aproximadamente [matemáticas] N * \ pi / 4 [/ matemáticas] de esos puntos deben caer dentro del círculo.
Luego recogemos puntos al azar dentro del cuadrado y luego verificamos si el punto está dentro del círculo. Si el punto está dentro del círculo, entonces

[matemáticas] x ^ 2 + y ^ 2

la ecuación se satisface donde x e y son las coordenadas del punto y R es el radio del círculo). El programa realiza un seguimiento de cuántos puntos se seleccionó hasta ahora (N) y cuántos de esos puntos cayeron dentro del círculo (M).
[math] \ pi [/ math] se aproxima de la siguiente manera:

[matemáticas] \ pi [/ matemáticas] = 4 * M / N

o alternativamente

[matemáticas] \ pi [/ matemáticas] = 4 * [matemáticas] A_ {círculo} / A_ {cuadrado} [/ matemáticas]


Código :

importar al azar
matemáticas de importación

def dentro del círculo (x, y):
si (x ** 2 + y ** 2 <1):
volver verdadero
más:
falso retorno

if __name__ == ‘__main__’:
circleArea = 0
squareArea = 0
pi = 0
para i en rango (0,100000):
x = random.random ()
y = random.random ()
if (dentro del círculo (x, y) == 1):
circleArea = circleArea + 1
squareArea = squareArea + 1
pi = 4.0 * circleArea / squareArea
print “Valor aproximado para pi:”, pi
print “Diferencia al valor exacto de pi:”, pi-math.pi
print “Error: (aprox-exacto) / exacto =”, (pi-math.pi) /math.pi*100, “%”


Referencias : Cálculo de Pi usando el método de Monte Carlo, Calculando Pi con el método de Monte Carlo

Solo quiero agregar una cosa: ¡pruebe algo más creativo! Si eres lo suficientemente paciente (realmente paciente), ¡puedes estimar el valor deseado de pi incluso sin una computadora!

Tome una hoja de papel grande y dibuje un montón de líneas paralelas con una distancia de 2a entre sí. Tome una aguja de la longitud 2 l que sea igual a 2 a (dicha parametrización se toma solo por simplicidad). Obtenga palomitas de maíz y comience a tirar la aguja al azar sobre el papel, contando el número total de intentos y el número de instancias en que la aguja cruza una de esas líneas.

Una vez que las palomitas hayan terminado, calcule la probabilidad de que la aguja cruce alguna línea. En teoría, debería ser 2 / pi, por lo que este método le ofrece una forma de estimar pi. ¡Que te diviertas!

Esto viene del problema de la aguja de un famoso Buffon.

Bueno, un código simple de C ++ para encontrar ‘pi’ podría ser:
#include
#include

usando el espacio de nombres estándar;
int main ()
{
cout << 4 * atan (1.0) << "\ n";
devuelve 0;
}
La salida en mi computadora es: 3.14159

El código anterior da un buen resultado, sin embargo, hay mejores aproximaciones disponibles. Puede consultar la siguiente página de Wikipedia
Aproximaciones de π

Se puede usar el hecho de que, [matemáticas] -1 \ leq x \ leq 0 \ implica \ frac {1} {1 + x ^ 2} = \ lim \ limits_ {n \ to \ infty} \ sum_1 ^ n {( -x) ^ n} = \ sum_1 ^ n {(- 1) ^ nx ^ n} [/ math]

Pero [math] \ frac {\ partial} {\ partial x} (\ arctan (x)) = \ frac {1} {1 + x ^ 2} [/ math]

Entonces, dado que [math] \ frac {\ partial} {\ partial x} (\ arctan (x)) [/ math] es continuo,

[matemáticas] \ int \ frac {\ partial} {\ partial x} (\ arctan (x)) dx = \ arctan (x) [/ math]

Entonces, [matemáticas] \ arctan (x) = \ int \ frac {1} {1 + x ^ 2} dx = \ int \ lim \ limits_ {n \ to \ infty} \ sum_1 ^ n (-1) ^ nx ^ n dx = \ lim \ limits_ {n \ to \ infty} \ sum_0 ^ n (-1) ^ {n} \ frac {x ^ {2n + 1}} {2n + 1} [/ math]

Ahora solo use el hecho de que [math] \ arctan (1) = \ frac {\ pi} {4} [/ math], y conéctelo en la serie anterior usando tantos términos como desee.

[matemáticas] \ arctan (1) = \ sum_0 ^ n (-1) ^ {n} \ frac {1 ^ {2n + 1}} {2n + 1} = 1- \ frac {1} {3} + \ frac {1} {5} -… = \ frac {\ pi} {4} [/ math]

Como esta es la expansión de Taylor de [math] \ arctan (x) [/ math], cuando utiliza los términos [math] k [/ math] en su aproximación, el resto son solo los términos que no tuvo en cuenta, que es:

[matemáticas] r_k (x) = (-1) ^ k \ int_0 ^ x \ frac {t ^ {2k}} {1 + t ^ 2} dt \ leq \ frac {1} {2k + 1} [/ matemáticas ]

Entonces, el error que comete al usar los términos [math] k [/ math] es menor que [math] \ frac {1} {2k + 1}. [/ Math]

Ahora, si desea calcular 2.7 billones de dígitos de [math] \ pi [/ math], entonces su error debe ser menor que [math] \ frac {1} {10 ^ {13}}. [/ Math] Entonces resolviendo [ matemáticas] \ frac {1} {2k + 1} <\ frac {1} {10 ^ {13}} \ implica k> \ frac {(10 ^ {13} – 1)} {2} [/ matemáticas]

Todavía hay muchos términos que necesitarías. Pero creo que es factible usar una computadora doméstica normal.

Observe que esta no es la única forma de hacerlo y no es la forma más rápida (por ejemplo: el método que brinda una mejor convergencia de la función de error [math] r_k (x) [/ math]). Pero es muy simple.

EDITAR: También debe preocuparse por los problemas numéricos al evaluar la suma en un programa de computadora, ya que la precisión de coma flotante debe tenerse en cuenta. Los términos de la suma son cada vez más pequeños y habrá un error de truncamiento debido al límite de la representación de la mantisa en números de coma flotante. Puede usar implementaciones de gran número en C ++ o C para evaluar esto. Esto realmente sucederá con cualquier algoritmo o método que use que haga sumas para acumular los resultados parciales. Consulte la biblioteca GMP https://gmplib.org para obtener números de precisión arbitrarios en C.

Hay al menos dos formas:

  1. Usando una expansión en serie. Por ejemplo, la fórmula de Leibniz: 4 – (4/3) + (4/5) – (4/7) + …
  2. Usando el método de Montecarlo para encontrar el área de un círculo de unidad de radio (varias respuestas ya han cubierto esto).

Ahora, el método 1 converge mucho más rápido que el método 2.

Pero mi técnica favorita personal es esta (aquí en Python):

de importación matemática *
resultado = pi
resultado de impresión

Calcule el valor de pi usando series infinitas.

Imprima una tabla que muestre el valor de pi aproximado por un término de esta serie, por dos y por tres términos, etc. ¿Cuántos términos de esta serie debe usar antes de obtener 1.14? 3.141? 3.1415? 3.14159?
(Así es como lo hacemos en C ++)

#include

int main ()
{
int i;
doble p = 0;
para (i = 1; i <= 100; i ++)
{
si (i% 2 == 0)
{
p = p – (4.0 / (2 * i – 1));
}
más
{
p = p + (4.0 / (2 * i – 1));
}
printf (“% f \ t”, p);
}
devuelve 0;
}

Los resultados impresos se amplían mucho de los valores que tengo que imprimir en la pregunta, ¿se supone que debo usar la división en el código? ¿He escrito el código correctamente?

Primero, necesitará una biblioteca de números de alta precisión para almacenar y trabajar con números con más dígitos. Suponiendo que tiene eso, ¿por qué no probar un enfoque de búsqueda de raíz?

Por ejemplo, sabemos [math] \ sin (x) = 0 [/ math] en [math] x = \ pi [/ math]. Entonces, ¿qué tal si tratamos de estimar [matemáticas] \ pi [/ matemáticas] al encontrar esta raíz, usando una suposición inicial de 3 o algo así?

Un buscador de raíces más convergente, aunque similar, que Newton es el siguiente:

[matemáticas] x_ {n + 1} = x_ {n} – \ frac {f (x_ {n})} {f ^ {‘} \ left (x – \ frac {f (x_ {n})} {2 f ‘(x_ {n})} \ right)} [/ math]

Entonces sabemos que [math] f (x) = \ sin (x), f ^ {‘} (x) = \ cos (x) [/ math]. Usando estas fórmulas, y una suposición inicial para [matemáticas] \ pi [/ matemáticas], que podría ser [matemáticas] x_ {0} = 3 [/ matemáticas] o [matemáticas] x_ {0} = 3.1415 [/ matemáticas], Esto debería converger rápidamente. Cuando implementé un código de muestra en Matlab, convergió a una precisión de máquina doble en 4 iteraciones con una suposición inicial de 3.

Hay un programa en Windows para pruebas de estrés de CPU y también en partedmagic CD de arranque que calcula el pi sin fin. Puedes buscar en Google ese programa. Desde su linux, también puede encontrar su código fuente. Si obtengo el código fuente, actualizaré mi respuesta.

La fórmula de Bellard – Wikipedia

Fórmula Bailey – Borwein – Plouffe – Wikipedia

Computación π – MATLAB y Simulink

Puedes descargar esto. Este es el método más rápido.

Este es un método paralelo. Se usa para calcular cada dígito de pi. Para que pueda enhebrarlo y calcularlo, se usa en tablas de búsqueda.

No voy a escribir todo aquí porque ya está en Wikipedia y en estos enlaces.

Cleve’s Corner Computing Pi – Intercambio de archivos – MATLAB Central

Códigos C

http://www.experimentalmath.info

El algoritmo de Bailey-Borwein-Plouffe en C # y F #

C # y F #

Prueba el código aquí

Primero, debe usar algún paquete que pueda manejar una cantidad arbitrariamente grande de dígitos. Luego, puede usar una fórmula iterativa como una de las iteraciones mencionadas en el archivo vinculado.

http://gcrhoads.byethost4.com/Co

Si tiene una computadora con Windows o Linux, puede usar “y-cruncher”, que se puede descargar en: Un programa Pi multiproceso

A menos que se especifique en la especificación, esto es lo que siempre hago para obtener pi

#include
#include
usando el espacio de nombres estándar;

int main () {
cout << acos (-1);
}