Calcular Pi

Iniciado por JonaLamper, 17 Octubre 2014, 09:22 AM

0 Miembros y 1 Visitante están viendo este tema.

JonaLamper

Buenas,

Resulta que el otro día me aburría en clase, tuve una idea y quisiera ver si es posible hacerlo.

Lo que quería hacer es algún tipo de bucle que me fuera cogiendo los dígitos del número Pi y me los vaya almacenando en algún sitio (a saber en cuál).

Supongamos dos cosas:

- Que quiero ir guardando dígito a dígito (en cada iteración del bucle)
- Que Pi no es infinito.

En abstracto, lo que quería hacer es:

while -mientras tamaño de acumulador sea mayor que tamaño de acumulador en la iteración anterior- (lo cual significa que ha guardado un dígito en la última iteración) entonces:

     lee el siguiente dígito de Pi y almacenalo
     incrementa el tamaño de acumulador


Con lo cual, iría leyendo los dígitos de Pi y guardándolos uno a uno. Hasta que en una cierta iteración ya no hubiese ningún dígito que guardar (pues hemos dicho "si Pi fuera finito") con lo cual el tamaño de acumulador ya no es mayor que el tamaño de acumulador en la iteración anterior y saldría del bucle.


¿Problemas? ¿Mejoras? ¿Especificación más concreta? Hablen  ;D


Utilizar palabras para hablar de palabras es como utilizar un lápiz para hacer un dibujo de ese lápiz sobre el mismo lápiz.

Eleкtro

#1
1) El tamaño del cálculo aritmético va a estar siempre sujeto a la limitación de las capacidades de computación del lenguaje que utilices. Probablemente vaya a estar limitado a un número no mayor  de 64 o 32 Bits de almacenamiento.


2) La longitud de un String (útil ejemplo de espacio donde insinuas que quieres almacenar digito por dígito por la razón que sea), también está limitada, y puede que en la mayoría de los casos el límite sea un número muy pequeño que no supere los 65534, es decir, la capacidad máxima de un número de 16 Bits, unsigned. En otros lenguajes, llega a ser incluso menor.


3) La limitación de la capacidad de almacenamiento de un String es fácil de evitar, ya que podrías enviar y escribir los datos a un archivo de texto, y entonces podrías resetear la variable a Null para no sobrepasar el máximo límite de longitud permitido, pero esto sería una locura, ya que el tiempo necesario de lectura y escritura en el disco cuando llevases una gigantesca cantidad de digitos acumulados en el interior del archivo de texto... sería algo terrorífico e inaguantable, no lo recomiendo.


4) En Python (por ejemplo) seria muy distinto, ya que la capacidad máxima es equivalente a la memoria RAM de la que dispongas para realizar la operación, es decir, cientos de miles (sino millones) de dígitos, y de caracteres.

Por lo tanto... poder, quizás se pueda llegar a un número gigantesco del valor de PI si elijes un lenguaje que te permita realizar las operaciones necesarias.

De todas formas si esto te lo has propuesto por curiosidad o como reto personal pues me parece bien, pero si lo haces para intentar calcular el número más grande entonces me parece una pérdida de tiempo, ya que hay webs y ftps que recopilan millones de digitos del PI, no es necesario desarrollar un Script si ya hay alguien que lo hizo. por ejemplo, en esta página muestran los 10.000 primeros dígitos del PI: http://www.ilikepi.com/10-000-digits-of-pi/


EDITO: Perdón, escribí los ejemplos de abajo pensando mientra escribia que este post estaba publicado en la sección de programación general xD, no tiene que ver con el Scripting, pero te podría servir de todas maneras.

EDITO2: Muevo el tema a Programación General, ya que la duda no está sujeta a ningún lenguaje específico.

5) Te muestro otra forma de iterar los dígitos de un valor numérico (el PI común de 16 dígitos), esto lo he escrito en VB.NET, pro lo puedes tomar como ejemplo y/o pseudo-código para otro(s) lenguajes(s), la idea básica es simplificar la utilización de un búcle de tipo While/Until y la creación de variables innecesarias de contadores (o acumuladores como tú lo denominas) siempre que el lenguaje te lo permita (como es en este caso, y en C# sería practicamente igual):

Código (vbnet) [Seleccionar]
For Each c As Char In Convert.ToString(Math.PI) '.Replace(","c, String.Empty)

   Console.Write(c)

Next c


6) La forma en la que tú has planteado el desarrollo del ejercicio, traducido a VB.Net podría llevarse a cabo de la siguiente manera, la cual te la muestro por si te sirve como idea, todo depende de cuantos digitos quieras sacar del PI...:

Código (vbnet) [Seleccionar]
' Estas instrucciones sirven para especificar la lozalización del formato de un String,
' para posteriormente reemplazar/eliminar el separador de decimales del número PI de la manera correcta,
' es decir, compatible con cualquier representación del separador de decimales de cualquier idioma.
Dim formatProvider As NumberFormatInfo = DirectCast(CultureInfo.CurrentCulture.NumberFormat.Clone, NumberFormatInfo)
With formatProvider
   .NumberDecimalSeparator = Microsoft.VisualBasic.vbNull
End With

Dim pi As String = Math.PI.ToString(String.Empty, formatProvider)
Dim data As String = String.Empty
Dim counter As Double = 0.0R

Do Until counter = pi.Length

   data &= pi(counter)
   counter += 1

   Console.WriteLine(data)

Loop


Saludos.








JonaLamper

#2
Lo primero, gracias.

No sabía nada acerca de qué tipo de lenguaje usar.

Veamos... a ver si sé explicar el mayor problema que yo veo (y si lo he entendido bien):

En python, yo podría calcular esos millones de dígitos y guardarlos (cuando mi RAM esté llena). Entonces podría almacenarlos en algún otro sitio y así poder vaciar la RAM para que comience de nuevo. ¿Hasta aquí voy bien?

La cosa es que cuando comience de nuevo, obligatoriamente lo tendrá que hacer por el 3,14159... no por el último dígito en el que se quedó (la vez anterior, cuando llenamos la RAM por primera vez). ¿Me explico?

Con lo cual, ¿existe alguna forma de que yo pudiera seguir con el bucle y que fuese almacenando los dígitos a partir del dígito por el que se quedó la última vez?

Y si fuera posible, en principio yo podría ir llenando la RAM, vaciarla, llenarla, vaciarla... y así, ir almacenando en un sitio con MUCHO espacio todos los dígitos que fuera recorriendo (hasta ver si es finito  :silbar:).

PD: bueno, esto último es bastante improbable  ;D

PD2: no lo hago por descubrir nada, solo quiero encontrar una forma de ir recorriendo Pi hasta que... llene 4 TB con solo dígitos  :xD
Utilizar palabras para hablar de palabras es como utilizar un lápiz para hacer un dibujo de ese lápiz sobre el mismo lápiz.

Eleкtro

#3
Cita de: JonaLamper en 17 Octubre 2014, 12:45 PMEn python, yo podría calcular esos millones de dígitos y guardarlos (cuando mi RAM esté llena). Entonces podría almacenarlos en algún otro sitio y así poder vaciar la RAM para que comience de nuevo. ¿Hasta aquí voy bien?

Sí, aunque debes dejar un margen preventivo para no comerte TODA la memoria disponible, ya que esto repercutiría en el rendimiento y comportamiento del resto de aplicaciones y del SO en general.

Además, si llegas al límite de RAM, por seguridad cualquier lenguaje lanzará una excepción de desbordamiento de memoria, excepción que deberás controlar en tu aplicación para no detenr imprevisiblemente su ejecución.

Ten en cuenta estas definiciones:
Buffer overflow
Stack overflow


CitarLa cosa es que cuando comience de nuevo, obligatoriamente lo tendrá que hacer por el 3,14159... no por el último dígito en el que se quedó (la vez anterior, cuando llenamos la RAM por primera vez). ¿Me explico?

Con lo cual, ¿existe alguna forma de que yo pudiera seguir con el bucle y que fuese almacenando los dígitos a partir del dígito por el que se quedó la última vez?

Supongo que te refieres a que la variable numérica deberá seguir por el número donde lo dejó, ya, ese es el problema y no se me ocurre como bypassear esa limitación (por eso no comenté nada al respecto), quizás no sea posible ya que, usando Python, sería un límite impuesto en las capacidades del propio Hardware, no creo que haya nada que hacer contra eso, ni tampoco que exista ningún Hack que puedas utilizar en "X" lenguaje para bypassear ese tipo de limitación en la capacidad de una variable, aunque esto último podría ser probable, no bypasseando el límite impuesto en el lenguaje, sino recurriendo a otro tipo de metodologías para llevar a cabo el mismo cálculo con menos información de la necesaria, no se, siempre hay Hacks sorprendentes para ciertos casos, y lo mio no son las matemáticas, todo hay que decirlo, jeje.


Cita de: JonaLamper en 17 Octubre 2014, 12:45 PMPD2: no lo hago por descubrir nada, solo quiero encontrar una forma de ir recorriendo Pi hasta que... llene 4 TB con solo dígitos  :xD

Esto te lo digo sin cachondeo, ¿eres consciente de que en un equipo "normal", el tiempo de ejecución de ese procedimiento/algoritmo llegaría a tardar semanas o meses en finalizar?.

Si realmente estás dispuesto, ya puedes hacerte a la idea de que si lo pretendes hacer más o menos decente entonces debes desarrollar una buena GUI o CLI que permita la posibilidad de detener y reanudar el proceso en cualquier momento... ya que el PC necesitará apagarse para descansar por las noches, y además deberás perfeccionar el rendimiento de la aplicación generando múltiples archivos de texto pequeños que en nigun caso superen los 100 mb, no sin olvidarnos de añadirle soporte multi-threading a la aplicación, IMPORTANTISIMO, y soporte multi-core, para que los distintos threads no compartan un único core y así sacarle el máximo provecho. Si lo haces de esa manera entonces tardarás menos tiempo en desarrollar la aplicación, que en llenar esos 4 TB de información.

Saludos!








JonaLamper

Uh... cuánto jaleo jajaja
Utilizar palabras para hablar de palabras es como utilizar un lápiz para hacer un dibujo de ese lápiz sobre el mismo lápiz.

engel lex

#5
voy a dejar el tema que hice hace tiempo sobre esto, al final creo que sacaba 1 millon de digitos en unos 15 minutos

https://foro.elhacker.net/programacion_cc/calculo_de_pi_en_alta_precision_aporte-t412338.0.html;msg1934259#msg1934259

el tema es que para salir del lio de la limitacion 32/64 bit, usas aritmetica de precision arbitraria


agrego:

el asunto de pi es que no puedes ir simplemente calculando digito por digito, sino que es un acumulativo, eso lo hace dificil porque tienes que reprocesar todo lo que tienes para sacar los decimales, con el segundo metodo que investigué saca 8 decimales por ciclo y hubo uno que me ganó que daba 15 decimales por ciclo
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Eleкtro

#6
Cita de: engel lex en 17 Octubre 2014, 14:34 PM
voy a dejar el tema que hice hace tiempo sobre esto, al final creo que sacaba 1 millon de digitos en unos 15 minutos

https://foro.elhacker.net/programacion_cc/calculo_de_pi_en_alta_precision_aporte-t412338.0.html;msg1934259#msg1934259

el tema es que para salir del lio de la limitacion 32/64 bit, usas aritmetica de precision arbitraria

agrego:

el asunto de pi es que no puedes ir simplemente calculando digito por digito, sino que es un acumulativo, eso lo hace dificil porque tienes que reprocesar todo lo que tienes para sacar los decimales, con el segundo metodo que investigué saca 8 decimales por ciclo y hubo uno que me ganó que daba 15 decimales por ciclo


Simplemente genial ese aporte, lo que dices que consigue, y la forma en la que lo consigue, se nota la diferencia entre alguien que tiene mucha (o la suficiente) experiencia con la aritmética, y alguien que no xD, me pierdo con las fórmulas.




Yo hice de informador más que nada sobre distintos aspectos que se deben tener en cuenta al llevar a cabo este tipo de tareas/operaciones a tales magnitudes, ya que como supuse desde un principio debía existir una solución simplificada que obviamente no debiera necesitar la escritura de archivos de texto y la ralentización que eso supone, solo había que hallar la metodología apropiada para llevar a cabo la tarea y así evitar esos límites de 32/64 Bits (como consiguió @Engel Lex), pero como ya dije antes, las matemáticas no son lo mio, ¡lo siento!.

Un saludo!