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

 

 


Tema destacado: Introducción a Git (Primera Parte)


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

Desconectado Desconectado

Mensajes: 13


Ver Perfil
Problema con ciclos (ejercicio de pi)
« en: 29 Marzo 2014, 01:48 am »

El ejercicio a programar es el siguiente:
Desarrolla una función que calcule el valor de π a partir de una serie indicada a
continuación, de la cual calcularemos la cantidad de términos indicados por el usuario.
π = 4 – 4/3 + 4/5 – 4/7 + 4/9 - ... ± 4/n
Mi idea fue crear el siguiente algoritmo:
Código
  1. #include <iostream>
  2. using namespace std;
  3. int main (){
  4. int b=0,a=1,i,c=0 ;
  5. int n;
  6. cout<<"Ingrese el numero"<<endl;
  7. cin>>n;
  8. if(n%2==0){
  9. cout<<"numero invalido"<<endl;
  10. }else{
  11. for(i=1;i<=n;i++){
  12. if(i%2==0){
  13. while(a<=n){
  14. b=b-(4/a);
  15.                 a=a+2;
  16. }
  17. cout<<b<<endl;
  18. }else{
  19. while(a<=n){
  20. c=c+(4/a);
  21. a=a+2;
  22. }
  23. cout<<c<<endl;
  24. }
  25. }
  26. }
  27. }
  28.  
Lo que no entiendo es porque no me da, según mi lógica y un pseudocodigo que hice eso debería funcionar...Por favor, podrían decirme en que me equivoque.


En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #1 en: 29 Marzo 2014, 03:37 am »

uff una serie de errores XD...


primero
Código
  1. if(n%2==0){
  2. cout<<"numero invalido"<<endl;

por que si es par es invalido? es una progresion, toma presicion al avanzar, la paridad no importa en valores altos...

Código
  1. int b=0,a=1,i,c=0 ;
  2. for(i=1;i<=n;i++){
  3.  if(i%2==0){
  4.    while(a<=n){
  5.      b=b-(4/a);
  6.      a=a+2;
  7.    }
  8.    cout<<b<<endl;
  9.  }else{
  10.    while(a<=n){
  11.      c=c+(4/a);
  12.      a=a+2;
  13.    }
  14.    cout<<c<<endl;
  15.  }
  16. }

el error es que es una sumatoria.... una UNICA sumatoria.... tu lo que estás haciendo son 2 sumatorias... una negativa y otra positiva... para ambos debe ser "b" el valor afectado

otra cosa...

sabemos que pi es un numero decimal, especialmente esta operación requiere de decimales... si te fijas la haces con enteros.... jamás dará resultado...




personalmente lo habría hecho así :P (super compacto XD)

Código
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int main(){
  5.    int precision, i = 0;
  6.    float pi = 4;
  7.    cout << "ingrese un grado de precision: ";
  8.    cin >> precision;
  9.    while (i++ < precision)pi += ((i%2==0?4:-4)/(1+i*2.0f));
  10.    printf ("\npi es: %.10f \n" , pi);
  11.    system("pause");
  12.    return 0;  
  13. }

desgloso un poquito:
-en la división hago algo similar a

Código
  1. if(i%2==0) {
  2.    pi = pi + (4 / (i*2.0f) );
  3. }else{
  4.    pi = pi - (4 / (i*2.0f) );
  5. }

este 2.0f es para que se force como flotante el resultado de la división, si no, la división quedará como entero (por ejemplo si haces 4/i, al ser i entero, el resultado es entero)

-en la impresión de datos no uso cout, sino printf con el valor "%.10f" esto significa que va a imprimir 10 decimales (aunque sean ceros)

espero sea de ayuda inténtalo correr con un valor de 1000000000 :P mi maquina lo corre en unos 20 seg y el valor dudo que lo puedas tener más aproximado XD


« Última modificación: 29 Marzo 2014, 03:39 am por engel lex » En línea

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.
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #2 en: 29 Marzo 2014, 15:23 pm »

El ejercicio a programar es el siguiente:
Desarrolla una función que calcule el valor de π a partir de una serie indicada a
continuación, de la cual calcularemos la cantidad de términos indicados por el usuario.
π = 4 – 4/3 + 4/5 – 4/7 + 4/9 - ... ± 4/n
..................................................
Lo que no entiendo es porque no me da, según mi lógica y un pseudocodigo que hice eso debería funcionar...Por favor, podrían decirme en que me equivoque.

* Para empezar las instrucciones:

Código
  1. if(n%2==0){
  2.  cout<<"numero invalido"<<endl;
  3.  


están de más ya que se puede pedir un número par de términos de la sucesión. Otra cosa es que los términos de la sucesión sólo contengan números impares, pero yo puedo pedir tres o cuatro términos.

* En:


Código
  1. if(i%2==0){
  2.  while(a<=n){
  3.    b=b-(4/a);
  4.    a=a+2;
  5.  }

te sobra el while. Tal como lo tienes calcularías para cada i todos los términos de la sucesión. Y en el otro while lo mismo, además no tienes por cambiar el nombre de la variable, sigue usando b en lugar de c.

* Deberías declarar como float, ya que son valores que implican el cálculo de  decimales, a las variables b y a.

* Te falta el return de la función main e indentar el código de forma correcta.

Con esto el código corregido y funcionando;

Código
  1. #include <iostream>
  2. using namespace std;
  3. int main (){
  4.  int n,i ;
  5.  float  b=4,a=3;
  6.  cout<<"Ingrese el numero de terminos: ";
  7.  cin>>n;
  8.  cout<<endl<<endl<<"a["<<1<< "]= "<<b<<endl;
  9.  for(i=1;i<n;i++){
  10.    if(i%2!=0){
  11.      b=b-(4/a);
  12.      a=a+2;
  13.      cout<<"a["<<i+1<< "]= "<<b<<endl;
  14.    }
  15.    else{
  16.      b=b+(4/a);
  17.      a=a+2;
  18.      cout<<"a["<<i+1<< "]= "<<b<<endl;
  19.    }
  20.  }
  21.  return 0;
  22. }}

También podrías habar hecho un for que recorra sólo los impares y te ahorrarías un else y el uso del operador "%":

Código
  1. #include <iostream>
  2. using namespace std;
  3. int main (){
  4.  int N,n,signo=-1 ;
  5.  float  b=1,i;
  6.  cout<<"Ingrese el numero de terminos: ";
  7.  cin>>n;
  8.  N=2*n-1;
  9.  for(i=3;i<=N;i+=2,signo*=-1)
  10.    b+=(1/i)*signo;
  11.  cout<<"Pi= " <<4*b<<endl;
  12.  return 0;
  13. }

Citar
Ingrese el numero de terminos: 9


a[1]= 4
a[2]= 2.66667
a[3]= 3.46667
a[4]= 2.89524
a[5]= 3.33968
a[6]= 2.97605
a[7]= 3.28374
a[8]= 3.01707
a[9]= 3.25237

Process returned 0 (0x0)


Claro que si de lo que se trata es de calcular Pi y no es necesario imprimir cada termino del sumatorio, podrías hacer:

Código
  1. #include <iostream>
  2. using namespace std;
  3. int main (){
  4.  int n,signo=-1 ;
  5.  float  b=1,i;
  6.  cout<<"Ingrese el numero de terminos: ";
  7.  cin>>n;
  8.  for(i=3;i<=2*n-1;i+=2,signo*=-1)
  9.    b+=(1/i)*signo;
  10.  cout<<"Pi= " <<4*b<<endl;
  11.  return 0;
  12. }

Citar
Ingrese el numero de terminos: 1000000
Pi= 3.1416

Process returned 0 (0x0)   execution time

¡¡¡¡ Saluditos! ..... !!!!



  
« Última modificación: 29 Marzo 2014, 19:57 pm por leosansan » En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #3 en: 29 Marzo 2014, 17:48 pm »

Bueno, reconociendo el término general de la sumatoria (algo que siempre es bueno hacer):

  4 * (-1)^n
--------------
  2 * (n - 1)

para n desde 1 hasta infinito (o hasta el máximo N impuesto por el usuario), quedaría el código siguiente donde la idea (debida a leosansan en un post similar) de usar una bandera de signo que conmute de +1 a -1 en cada iteración nos evita tener que estar viendo si n es par o impar, quedaría:
Código
  1. int main()
  2. {
  3.   double numero;
  4.   int n, N;
  5.   int signo;
  6.  
  7.   cout << "numero de terminos: ";
  8.   cin >> N;
  9.   cout << endl;
  10.  
  11.   numero = 4;
  12.   signo = -1;
  13.   for ( n = 1; n <= N; i++, signo*=-1 ) {
  14.      cout << "a[" << i << "] = " << numero << endl;
  15.      numero += signo * 4. / (2*n + 1);
  16.   }
  17.  
  18.   return 0;
  19. }
  20.  

donde el punto en "4." obliga la división entre doubles en lugar de enteros (gracias de nuevo por la acotación leosansan).
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #4 en: 29 Marzo 2014, 20:19 pm »

Amigo yoel_alejandro de corazón que todo es en plan buen rollo, nada de suspicacias, please!.

Antes que nada creo que se te fue un gazapo en la expresión:

...............................................................

  4 * (-1)^n
--------------
  2 * (n - 1)

..........................................

Creo que tu intención era poner:

Citar

  4 * (-1)^n
--------------
 (2*n - 1)


Por otro lado:

.......................................
donde el punto en "4." obliga la división entre doubles en lugar de enteros (gracias de nuevo por la acotación leosansan).


Esta vez no me ha hecho falta lo del "4.", es decir lo del punto decimal, al declarar la variable i como float.

Por otro lado, al ser el mismo problema que en el otro tema del número Pi, he observado esta vez que me puedo ahorrar dos operaciones en cada ciclo del bucle for usando 1/i donde i es impar al empezar el bucle en tres e incrementar de dos en dos:


Código
  1. ..................................
  2.  N=2*n-1;
  3.  for(i=3;i<=N;i+=2,signo*=-1)
  4.    b+=(1/i)*signo;
  5.  ......................................
  6.  

 que se corresponden con las que hacíamos en 2*n-1: una multiplicación y una resta en cada ciclo. Y teniendo en cuenta que para que la serie propuesta nos dé 3.1416 hay que tomar un millón, n=1 000 000, de sumandos, nos queda que con el nuevo for que propongo en el último mensaje, me ahorro dos millones de operaciones, de ahí que lo cambiará respecto del otro tema.

¡¡¡¡ Saluditos! ..... !!!!



« Última modificación: 29 Marzo 2014, 20:36 pm por leosansan » En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #5 en: 29 Marzo 2014, 21:04 pm »

tiempo de ejecucion... mi codigo...

Código
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <time.h>
  4. using namespace std;
  5. int main(){
  6.    int precision, i = 0;
  7.    float pi = 4;
  8.    cout << "ingrese un grado de precision: ";
  9.    cin >> precision;
  10.    clock_t tStart = clock();
  11.    while (i++ < precision)pi += ((i%2==0?4:-4)/(1+i*2.0f));
  12.    printf ("\npi es: %.10f \n" , pi);
  13.    printf("Time taken: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
  14.    system("pause");
  15.    return 0;  
  16. }
numero introducido: 10.000.000
resultado: 3.1415970325
tiempo: 0.2270
(con 1.000.000.000 tarda 22 sec)

codigo leosansan (modif para el tiempo)

Código
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <time.h>
  4. using namespace std;
  5.  
  6. int main(){
  7.    int n,signo=-1 ;
  8.    float  b=1,i;
  9.    cout<<"Ingrese el numero de terminos: ";
  10.    cin>>n;
  11.    clock_t tStart = clock();
  12.    for(i=3;i<=2*n-1;i+=2,signo*=-1)
  13.        b+=(1/i)*signo;
  14.    cout<<"Pi= " <<4*b<<endl;
  15.    printf("Time taken: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
  16.    system("pause");
  17.    return 0;  
  18. }
numero introducido: 10.000.000
resultado: 3.1416
tiempo: 0.0980
->anotacion... si metes 100.000.000 o más pasa más de 50 segundos sin hacer nada, me cansé de esperar


el codigo de yoel_alejando (modificado un par de errores, con "n" e "i" y que solo haga una impresion final

Código
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <time.h>
  4. using namespace std;
  5.  
  6. int main(){
  7.    double numero;
  8.   int n, N;
  9.   int signo;
  10.   cout << "numero de terminos: ";
  11.   cin >> N;
  12.   cout << endl;
  13.    clock_t tStart = clock();
  14.    numero = 4;
  15.   signo = -1;
  16.   for ( n = 1; n <= N; n++, signo*=-1 ) {
  17.      numero += signo * 4. / (2*n + 1);
  18.   }
  19.   cout << "pi es: " << numero << endl;
  20.    printf("Time taken: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
  21.    system("pause");
  22.    return 0;  
  23. }
  24.  
numero introducido: 10.000.000
resultado: 3.14159
tiempo: 0.0960
(con 1.000.000.000 tarda 10 sec)

el codigo de  yoel_alejandro es el ganador :P quedó muy eficiente :P ya veo que hiperresumir todo no es tan bueno

chicos usen printf es por el bien de todos o bueno de todos los decimales que fueron calculados en vano! XD
« Última modificación: 29 Marzo 2014, 21:06 pm por engel lex » En línea

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.
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #6 en: 30 Marzo 2014, 03:21 am »



Es por pasar el tiempo, ¡ehh!.

Las salidas de leosansan, engel lex y  yoel_alejandro por un millon, diez y mil millones, pero eso si en las mismas condiciones , incluso en el tipo de variables para lo que tuve que modificar mi código y declarar i como int, así estamos todos iguales:


















Como se ve estamos todos en un puño sin apenas diferencias.


¡¡¡¡ Saluditos! ..... !!!!



En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #7 en: 30 Marzo 2014, 03:28 am »

leosansan XD lo hice por ocio XD pero a mi por alguna razon en todas las corridas la de yoel me daba unos 10 segundos menos que el mio en 1.000.000.000 y el tuyo no andaba en más de 10.000.000 D:
En línea

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.
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #8 en: 30 Marzo 2014, 03:32 am »

El motivo que veo es que tenia declarada i como float. Al hacerlo como int todo va sobre ruedas.

Lo cierto es lo que comenté, estamos en centésimas de diferencias. ;)



¡¡¡¡ Saluditos! ..... !!!!


« Última modificación: 30 Marzo 2014, 03:38 am por leosansan » En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Problema con ciclos (ejercicio de pi)
« Respuesta #9 en: 30 Marzo 2014, 18:49 pm »

Vaya, ustedes sí que tienen ocio de ponerse a medir el tiempo con cada uno de los algoritmos, jaja!

Bueno, yo uso la filosofía del mínimo recurso, me parece lo más lógico declarar n como entero, pues la función que realiza es la de un entero. Tengan en cuenta que comparar dos float es más complicado, a nivel de máquina, que comparar dos enteros. Los float llevan mantisa y exponente, y supongo que nivel de bits primero se comparan los exponentes, y si son iguales se pasa a las mantisas. En cambio en los enteros se comparan todos sus bits de una vez y punto.

A pesar de ello yo hubiera supuesto que el manejo de leosansan, de sumar dos al contador n+=2 sería más eficiente que calcular 2*n+1 (suma y multiplicación incluida). Pero el ensayo demostró que fueron equivalentes, jeje, no se por qué.

Por otra parte, es cierto que resumir el código fuente no necesariamente reduce el tiempo de ejecución. Para lo segundo hay que ponerse a pensar en lo que traduce el compilador, y por ende la manera como se ejecuta el código a nivel de la máquina (los tipos de datos involucrados, etc). Es un punto que precisamente yo venía sosteniendo desde otro post.

Por supuesto, estas son cosas para entretenernos los usuarios más avanzados, no son cosas para considerar aún por la autora del tema quién está apenas comenzando a programar (algún día lo hará), jeje.

Saludos a todos  :D

En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
PROGRAMA USANDO CICLOS FOR
Programación C/C++
BOONE 5 8,752 Último mensaje 7 Diciembre 2011, 04:22 am
por ISCJAIRO
lio con ciclos...
Java
dvdza 1 1,986 Último mensaje 16 Diciembre 2012, 01:10 am
por kasiko
Ayuda Ejercicio c++ Ciclos Mientras y for
Programación C/C++
sergio011295 2 2,492 Último mensaje 2 Mayo 2013, 16:13 pm
por NoLife
¿Cómo calcular los ciclos por instrucción en este problema?
Electrónica
xemnas 2 4,902 Último mensaje 28 Octubre 2014, 11:17 am
por xemnas
Por favor ayúdenme, es un ejercicio de ciclos en python
Ejercicios
Ajrbar 2 3,673 Último mensaje 3 Junio 2020, 19:16 pm
por MCKSys Argentina
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines