elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [C]Calcular pi
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [C]Calcular pi  (Leído 31,088 veces)
HRSLASH

Desconectado Desconectado

Mensajes: 33



Ver Perfil
[C]Calcular pi
« en: 10 Agosto 2010, 19:47 pm »

Hola gente!! dejo unos programitas que hice para calcular pi con distintas series infinitas.. y ya q los posteo aprovecho para dejar unas dudas q tengo..

Algoritmo Gottfried Wilhem von Leibniz
= 4(1/1-1/3+1/5-1/7+1/9...)

Código
  1. #include<stdio.h>
  2.  
  3. main()
  4. {
  5.      int i, j = 1;
  6.      double pi = 0, rtdo;
  7.  
  8.      for (i = 0; i < 1000000000; i++){
  9.          rtdo = 4 / (double)j;
  10.  
  11.               if (i % 2 == 1)
  12.                  pi -= rtdo;
  13.               else
  14.                   pi += rtdo;
  15.          j += 2;
  16.      }
  17.  
  18.      printf("Valor de Pi: %.16f", pi);
  19.  
  20.      return 0;
  21. }
  22.  

Algoritmo John Wallis
= 2 ( 2/1 x 2/3 x 4/3 x 4/5 x 6/5 x 6/7 ....)

Código
  1. #include<stdio.h>
  2.  
  3. main()
  4. {
  5.      int i, j = 2, k = 1;
  6.      double pi = 2;
  7.  
  8.      for (i = 0; i < 1000000000; i++){
  9.          pi *= (j / (double)k);
  10.  
  11.          if (i % 2 == 0)
  12.             k += 2;
  13.          else
  14.              j += 2;
  15.      }
  16.  
  17.      printf("Valor de Pi: %.16f", pi);
  18.  
  19.      return 0;
  20. }
  21.  

Estos 2 funcionan bien pero me devuelven solo 16 decimales, desp de ese devuelve todo 0.. pq??

Algoritmo Leonhard Euler
=  1 + 1/3 + 1x2 / 3x5 + 1x2x3 / 3x5x7 +....

Código
  1. #include<stdio.h>
  2.  
  3. main()
  4. {
  5.      int i, cte = 1, cte2 = 1;
  6.      double pi = 1, j = 1, k = 1;
  7.  
  8.      for (i = 0; i < 100; i++){
  9.          j *= cte++;
  10.          k *= (cte2 += 2);
  11.  
  12.          pi += (j / k);
  13.          }
  14.  
  15.      printf("%.15f", pi);
  16.  
  17.      return 0;
  18. }
  19.  

En este tengo el problema de q como se forman nº tan grandes no puedo hacer un bucle de mas de 100 vueltas y ademas no da el rtdo, no pude encontrarle solucion, creo q el codigo esta bien hecho..

Saludos! :D


En línea

La televisión es para mi el medio mas instructivo y cultural que conozco, cuando la prenden me voy a leer
leogtz
. . .. ... ..... ........ ............. .....................
Colaborador
***
Desconectado Desconectado

Mensajes: 3.069


/^$/


Ver Perfil WWW
Re: [C]Calcular pi
« Respuesta #1 en: 10 Agosto 2010, 20:36 pm »

En el algoritmo "Algoritmo Gottfried Wilhem von Leibniz" corrigiendo errores, usando variables register y compilando "agresivamente" con gcc se puede calcular en unos 45 segundos a 32 decimales:

Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.      register unsigned long long int i, j = 2, k = 1;
  6.      long double pi = 2.0;
  7.  
  8.      for (i = 0; i < 1000000000; ++i)
  9.      {
  10.          pi *= (j / (double)k);
  11.  
  12.          if (!(i & 1))
  13.             k += 2;
  14.          else
  15.              j += 2;
  16.      }
  17.      printf("Pi : %.32llf\n", pi);
  18.      return 0;
  19. }
  20.  


Código:
leo@lein:~/Escritorio/c_proyect/intgrande$ cat code.c
#include <stdio.h>

int main(void)
{
      register unsigned long long int i, j = 2, k = 1;
      long double pi = 2.0;

      for (i = 0; i < 1000000000; ++i)
      {
          pi *= (j / (double)k);

          if (!(i & 1))
             k += 2;
          else
              j += 2;
      }
      printf("Pi : %.32llf\n", pi);
      return 0;
}
leo@lein:~/Escritorio/c_proyect/intgrande$ gcc code.c -O1 -O2 -O3 -o code
leo@lein:~/Escritorio/c_proyect/intgrande$ time ./code
Pi : 3.14159265201900078298691276756927

real    0m46.795s
user    0m44.851s
sys     0m0.072s
leo@lein:~/Escritorio/c_proyect/intgrande$ time ./code
Pi : 3.14159265201900078298691276756927

real    0m46.149s
user    0m44.575s
sys     0m0.052s
leo@lein:~/Escritorio/c_proyect/intgrande$

Y este:

Código:
#include <stdio.h>

int main()
{
      unsigned long long int i, cte = 1, cte2 = 1;
      long double pi = 1.0, j = 1.0, k = 1.0;

      for (i = 0; i < 1000; ++i)
      {
          j *= (double)cte++;
          k *= (double)(cte2 += 2);
          pi += (j / k);
          }

      printf("%.15llf", pi);

      return 0;
}
No creo que funcione, incluso con i <1000 no calcula bien:


Código:
leo@lein:~/Escritorio/c_proyect/intgrande$ ./code
1.570796326794897
leo@lein:~/Escritorio/c_proyect/intgrande$

Aquí otra manera de construirlo.

Código
  1. /* Construcción del número pi */
  2. #include <stdio.h>
  3. #include <math.h>
  4. int main(void)
  5. {
  6.    signed int i = 1;
  7.    long double suma = 0.0;
  8.    for(; i <= 1000000   ; i++)
  9.    suma += (double)pow(-1.0, i + 1.0) / (2.0 * i - 1.0);
  10.    suma *= 4.0;
  11.    printf("%.32llf\n", suma);
  12.    return 0;
  13. }
  14.  

Código:
leo@lein:~/Escritorio/c_proyect/intgrande$ cat code.c
/* Construcción del número pi */
#include <stdio.h>
#include <math.h>
int main(void)
{
    signed int i = 1;
    long double suma = 0.0;
    for(; i <= 1000000   ; i++)
    suma += (double)pow(-1.0, i + 1.0) / (2.0 * i - 1.0);
    suma *= 4.0;
    printf("%.32llf\n", suma);
    return 0;
}
leo@lein:~/Escritorio/c_proyect/intgrande$ gcc code.c -o code -O1 -O2 -O3 -lm
leo@lein:~/Escritorio/c_proyect/intgrande$ ./code
3.14159165358979318525417534502253
leo@lein:~/Escritorio/c_proyect/intgrande$ time ./code
3.14159165358979318525417534502253

real    0m0.276s
user    0m0.276s
sys     0m0.000s
leo@lein:~/Escritorio/c_proyect/intgrande$


« Última modificación: 10 Agosto 2010, 20:44 pm por Leo Gutiérrez. » En línea

Código
  1. (( 1 / 0 )) &> /dev/null || {
  2. echo -e "stderrrrrrrrrrrrrrrrrrr";
  3. }
  4.  
http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com
HRSLASH

Desconectado Desconectado

Mensajes: 33



Ver Perfil
Re: [C]Calcular pi
« Respuesta #2 en: 10 Agosto 2010, 23:23 pm »

Hola leo!! gracias por tu ayuda!! ahora tengo un problema.. cuando copio el codigo q escribiste y lo pego en el dev-c++, al compilarlo me muestra cualquier numero, esta copiado identico pero no funciona :-\ es pq no uso el gcc?
otra preg, pq usas el tipo register? y la ultima.. q significa esta condicion(i & 1), estaba mal la q habia puesto antes??
Bueno espero tu rta :D
Saludo!!
En línea

La televisión es para mi el medio mas instructivo y cultural que conozco, cuando la prenden me voy a leer
leogtz
. . .. ... ..... ........ ............. .....................
Colaborador
***
Desconectado Desconectado

Mensajes: 3.069


/^$/


Ver Perfil WWW
Re: [C]Calcular pi
« Respuesta #3 en: 20 Agosto 2010, 19:58 pm »

otra preg, pq usas el tipo register? y la ultima.. q significa esta condicion(i & 1), estaba mal la q habia puesto antes??
Bueno espero tu rta :D
Saludo!!

El código funciona bien con gcc que es el que uso, no sé como funcionará con MingW.

El especificador register pone las variables en un registro del CPU en lugar de estar en la memoria, es por esto que las operaciones con las variables register se hacen mucho más rápido.
En línea

Código
  1. (( 1 / 0 )) &> /dev/null || {
  2. echo -e "stderrrrrrrrrrrrrrrrrrr";
  3. }
  4.  
http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com
Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: [C]Calcular pi
« Respuesta #4 en: 20 Agosto 2010, 23:42 pm »

En realidad el especificador register no es mas que una "sugerencia", en todo caso es el compilador el que decide si hacer caso o no a esa "sugerencia".

En otras épocas se utilizaba, pero en la actualidad la complejidad subyacente es otra por tanto el compilador hace un mejor trabajo optimizando código que nosotros, por lo menos en la gran mayoría de los casos.

De hecho, Visual Studio ni siquiera acepta la sugerencia:

Citar
The compiler does not accept user requests for register variables; instead, it makes its own register choices when global register-allocation optimization (/Oe option) is on. However, all other semantics associated with the register keyword are honored.

y GCC lo ignora en caso que la dirección de la variable se solicite en cualquier punto del programa.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
leogtz
. . .. ... ..... ........ ............. .....................
Colaborador
***
Desconectado Desconectado

Mensajes: 3.069


/^$/


Ver Perfil WWW
Re: [C]Calcular pi
« Respuesta #5 en: 21 Agosto 2010, 03:04 am »

Claro, Littlehorse, pero qué mejor que decidirlo por nosotros mismos y no el compilador, es decir, ser lo más explícito posible.

En el ejemplo que puse solo se usa para control de bucles, así que no creo que haya problemas en eso.
En línea

Código
  1. (( 1 / 0 )) &> /dev/null || {
  2. echo -e "stderrrrrrrrrrrrrrrrrrr";
  3. }
  4.  
http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com
Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: [C]Calcular pi
« Respuesta #6 en: 21 Agosto 2010, 03:32 am »

Claro pero, repito, no es una decisión, es una sugerencia que el compilador es libre de ignorar por completo, y de hecho lo hacen en mas de una oportunidad.

Lo aclaro para que no quede la falsa idea que utilizar variables locales register si o si mejora el rendimiento de un programa, ya que esto solo ocurriría en ciertas oportunidades y solamente cuando el compilador lo decida. En el peor de los casos, demasiadas variables register podrían empeorar el rendimiento del programa final.

Saludos

En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
misterharry

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Re: [C]Calcular pi
« Respuesta #7 en: 23 Agosto 2010, 03:32 am »


q significa esta condicion(i & 1), estaba mal la q habia puesto antes??

en realidad no estaba mal...

& tambien es un operador binario (operador AND) y en este caso esta comparando el valor binario de "i" con 1
ej:
       si i=3 en binario seria 00000011, entonces 00000011 & 1 = 1
       si i=2 en binario seria 00000010, entonces 00000010 & 1 = 0

esta siendo utilizado para verificar si el numero es impar :)

es decir ( i & 1) es equivalente a (i % 2 == 1)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Calcular % con fechas
Programación Visual Basic
Mr.Chispa 2 1,757 Último mensaje 6 Septiembre 2006, 09:05 am
por Mr.Chispa
Calcular Altura
Programación Visual Basic
SheKeL_C$ 5 2,401 Último mensaje 7 Octubre 2006, 17:38 pm
por edge master
Calcular Borde Vb.Net
.NET (C#, VB.NET, ASP)
Keyen Night 2 2,891 Último mensaje 6 Abril 2010, 06:26 am
por Keyen Night
calcular c.
.NET (C#, VB.NET, ASP)
karmi 1 2,786 Último mensaje 4 Marzo 2011, 07:45 am
por .mokk.
Calcular el current time
Programación Visual Basic
iaorengo 9 4,335 Último mensaje 25 Noviembre 2011, 02:52 am
por seba123neo
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines