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

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [C] e^x, si x es grande, numero negativo
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [C] e^x, si x es grande, numero negativo  (Leído 5,759 veces)
edr89

Desconectado Desconectado

Mensajes: 105


Ver Perfil
[C] e^x, si x es grande, numero negativo
« en: 3 Junio 2013, 05:26 am »

Hola,
tengo que calcular el valor de e^x con la serie 1+x+((x^2)/2!)+((x^n)/n!)
encontre un tema relacionado, el código descrito da el mismo resultado que el que yo he hecho.

1- No estoy seguro si he definido bien las variables
2- Para numeros muy grandes el resultado es falso, se arroja un numero negativo, leí en otro tema que se debe definir una funcion que permita numeros muy grandes (a la hora de calcular el factorial) porque la compilacion tiene un limite.

¿Se puede definir una variable mayor a long long?

Como me ha sucedido en ocasiones anteriores, el programa funciona pero no tengo la certeza de que el código este bien escrito. Comentarios y sugerencias bienvenidas.

Código
  1. #include <stdio.h>
  2. #include <math.h>
  3. main()
  4. {
  5.    int e,respuesta,n;
  6.    float resultado=0;
  7.    printf("Calcular e^x\n ");
  8.    printf(" Valor de x: ");
  9.    scanf("%d",&respuesta);
  10.    printf(" Numero de terminos: ");
  11.    scanf("%d",&n);
  12.    for(e=n;e>1;e--)
  13.        {
  14.            resultado+= (pow(respuesta,n)) / (facto(n));
  15.            n--;
  16.        }
  17.    resultado += 1 + respuesta;
  18.  
  19.    printf("\ne^%d: %.4f",respuesta,resultado);
  20. }
  21.  
  22. facto(long long int num)
  23. {
  24.   int i=num;
  25.   long long fact=1;
  26.   for(i=num;i>1;i--)
  27.    {
  28.        fact*=i;
  29.    }
  30.    return fact;
  31. }
saludos!


En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #1 en: 3 Junio 2013, 07:22 am »

Hola,
tengo que calcular el valor de e^x con la serie 1+x+((x^2)/2!)+((x^n)/n!)

1- No estoy seguro si he definido bien las variables
2- Para numeros muy grandes el resultado es falso, se arroja un numero negativo, leí en otro tema que se debe definir una funcion que permita numeros muy grandes (a la hora de calcular el factorial) porque la compilacion tiene un limite.

¿Se puede definir una variable mayor a long long?


* Aparentemente as tienes bien definidas.

* Es el gran problema de C/C++, como el número entero tenga del orden de 20 cifras cruje, no da para más, sino prueba con 100 y 100 y veras.

* Tendría que repasar las nuevas librerías del estandar C99.

En todo caso el código que utilizas cojea en algunas cosas.

*  Por ejemplo, cuando se trata de calcular e^x el número de términos ha de ser algo secundario ya que lo que en realidad interesa es calcularlo con una determinada precisión, y es esa precisión la que determina automáticamente el número de términos a tomar. En tu caso podrías entrar 3^10 tomando 10 sumandos y no tendrías una referencia de la precisión de ese cálculo.

* Otro detalle es la ineficiencia de la forma de calcular e^x, en el sentido que utilizas pow, que en si mismo no está mal, y sobre todo en la forma de calcular el factorial, culpable en números grandes- el factorial crece muy rápidamente- con la combinación de pow. Ambos juntos hace que a poco que crezcan los números y el número de  términos de la serie a tomar obtengas resultados fuera del alcance o capacidades de C/C++.

* Un mejor método es tener en cuenta que e se calcula, utilizando el desarrollo en serie, de forma que cada nuevo sumando es el anterior multiplicado por un factor :x/n. Con este método alternativo no tienes ni que usar pow ni hacer el cálculo de factoriales previamente.

* Otra cosa a tener en cuenta es introducir una condición de precisión que determine de forma automática el número de sumandos a tomar.

* Y como último comentario a tu código, manejas pocos decimales para hacer cálculos de esta índole.

* También sería interesante comparar la diferencia entre el valor calculado con el valor exacto, entendiendo por éste el valor que de e^x daría la función e^x de la librería de math, que supongo hace uso de un algoritmo parecido al que te comento y paso a darte como variante del tuyo, y como muestra me da estas salidas:

Código
  1. Teclea el valor de x: 100
  2. Valor estimado: 2.688117141816136e+043
  3. Valor exacto: 2.688117141816136e+043.
  4. Error cometido: -1.525664384353662e+027 .
  5. Numero de terminos utilizados: 205
  6.  
  7. Teclea el valor de x: 500
  8. Valor estimado: 1.403592217852838e+217
  9. Valor exacto: 1.403592217852838e+217.
  10. Error cometido: -6.745532683619974e+200 .
  11. Numero de terminos utilizados: 716
  12.  
  13. Teclea el valor de x: 709
  14. Valor estimado: 8.218407461554972e+307
  15. Valor exacto: 8.218407461554972e+307.
  16. Error cometido: -1.900336232223e+291 .
  17. Numero de terminos utilizados: 964

Y el código para ello, que no se diga que no compartimos secretillos:

Código
  1. /* e^x
  2. *la condición de finalización de las iteraciones: para este ejercicio
  3. utilizamos un bucle while y dos series (con los nombres serie y
  4. serie2  ) cuya diferencia mutua esta en un término,es decir,
  5. serie2 tiene un término más que serie1 . La razón de esta forma de
  6. calcular la serie la encontramos una vez más en la capacidad de almacenamiento de las variables tipo double : la fracción que
  7. calculamos y que añadimos a la serie es cada  vez más pequeña
  8. y, por tanto, la diferencia entre las dos series  también. Llega
  9. un momento en el que las cifras significativas que   puede almacenar
  10. la variable no son apreciables y la fracción que  sumamos no
  11. representa cambio en las variables: en ese momento las  series
  12. toman el mismo valor, se igualan y, por tanto, se termina  la
  13.  ejecución del bucle*/
  14.  
  15. #include <stdio.h>
  16. #include <math.h>
  17. int main(void)
  18. {
  19.     double x, serie1, serie2, frac;
  20.     int i;
  21.     while (1)
  22.     {
  23.         printf("Teclea el valor de x: ");
  24.         scanf("%lf", &x);
  25.         serie1=1.0;
  26.         frac=x;
  27.         serie2=serie1+frac;
  28.         i=2;
  29.         while (serie1!=serie2)
  30.            {
  31.                 serie1=serie2;
  32.                 frac=frac*x/i++;
  33.                 serie2=serie1+frac;
  34.            }
  35.        printf("Valor estimado: %1.16g\n", serie2);
  36.        printf("Valor exacto: %1.16g.\n", exp(x));
  37.        printf("Error cometido: %1.16g .\n", exp(x)-serie2);
  38.        printf("Numero de terminos utilizados: %d\n\n", i);
  39.     }
  40.  
  41.    return 0;
  42. }
  43.  

* Existe otra variante para que el usuario indique la precisión con que quiere calcular e^x, pero eso te lo dejo como un simple ejercicio a partir del código anterior.

Saluditos!. ... ..


« Última modificación: 3 Junio 2013, 07:34 am por leosansan » En línea

flony


Desconectado Desconectado

Mensajes: 584



Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #2 en: 3 Junio 2013, 14:38 pm »

hola sobre el tema de los números grandes, estaba buscando para que sirven los int8_t int16_t etc, y salio un tema interesante que lo conseguí de casualidad, dependiendo del nivel de precisión podrías usar algo llamado "punto fijo"...no se si sirva, pero para leerlo y ver si te sirve...acá una cosa que encontré referido al tema
http://www.indicart.com.ar/seminario-embebidos/Elementos%20de%20C%20Embebido.pdf
En línea

si un problema no tiene solucion entonces no es un problema...es algo inevitable
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #3 en: 3 Junio 2013, 15:35 pm »

hola sobre el tema de los números grandes, estaba buscando para que sirven los int8_t int16_t etc, y salio un tema interesante que lo conseguí de casualidad, dependiendo del nivel de precisión podrías usar algo llamado "punto fijo"...no se si sirva, pero para leerlo y ver si te sirve...acá una cosa que encontré referido al tema


Por lo que tengo entendido, no logras más allá de los veinte dígito, en enteros, de los que obtendrías con un long long int. Otra cosa es que las nuevas librerías del C99 permiten un mayor control en la declaración del tipo de enteros en cuanto a su precisión/número de dígitos.

Saluditos!. .... ..
En línea

bemone

Desconectado Desconectado

Mensajes: 74



Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #4 en: 3 Junio 2013, 15:52 pm »

Perdon pero no lei mucho, leete el concepto de Sobrecarga de Funciones para poder utilizar el tipo acorde a tu situacion.
En línea

Odio los tipos de variable de Windows.
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #5 en: 3 Junio 2013, 16:58 pm »

Perdon pero no lei mucho, leete el concepto de Sobrecarga de Funciones para poder utilizar el tipo acorde a tu situacion.

 ¿Sobrecarga de Funciones en C? . Creo que debes leerte mejor los post anteriores.


Saluditos! ... ..
En línea

edr89

Desconectado Desconectado

Mensajes: 105


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #6 en: 4 Junio 2013, 05:05 am »

hola sobre el tema de los números grandes, estaba buscando para que sirven los int8_t int16_t etc, y salio un tema interesante que lo conseguí de casualidad, dependiendo del nivel de precisión podrías usar algo llamado "punto fijo"...no se si sirva, pero para leerlo y ver si te sirve...acá una cosa que encontré referido al tema
http://www.indicart.com.ar/seminario-embebidos/Elementos%20de%20C%20Embebido.pdf

Gracias, lo reviso con tiempo.

Código
  1. Teclea el valor de x: 100
  2. Valor estimado: 2.688117141816136e+043
  3. Valor exacto: 2.688117141816136e+043.
  4. Error cometido: -1.525664384353662e+027 .
  5. Numero de terminos utilizados: 205
  6.  
  7. Teclea el valor de x: 500
  8. Valor estimado: 1.403592217852838e+217
  9. Valor exacto: 1.403592217852838e+217.
  10. Error cometido: -6.745532683619974e+200 .
  11. Numero de terminos utilizados: 716
  12.  
  13. Teclea el valor de x: 709
  14. Valor estimado: 8.218407461554972e+307
  15. Valor exacto: 8.218407461554972e+307.
  16. Error cometido: -1.900336232223e+291 .
  17. Numero de terminos utilizados: 964

Perdon pero me cuesta trabajo entender el código, tengo que resolverlo con la formula 1+x+(x^n)/n!... por eso solo traduje a C usando la funcion pow y factorial.

Código
  1. while (serie1!=serie2)
  2.           {
  3.                serie1=serie2;
  4.                frac=frac*x/i++;
  5.                serie2=serie1+frac;


La solucion como tal no la puedo dar usando la funcion exp, forzosamente tengo que usar la formula con factorial  :(  (aunque aqui esta solo como referencia)

Me gusto mucho este otro código, lo reviso con tiempo. Yo estaba probando a hacerlo por partes para aprender a definir varias funciones y usarlas en main.

gracias y saludos!

En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #7 en: 4 Junio 2013, 05:48 am »

Gracias, lo reviso con tiempo.

Perdon pero me cuesta trabajo entender el código, tengo que resolverlo con la formula 1+x+(x^n)/n!... por eso solo traduje a C usando la funcion pow y factorial.

Código
  1. while (serie1!=serie2)
  2.           {
  3.                serie1=serie2;
  4.                frac=frac*x/i++;
  5.                serie2=serie1+frac;


La solucion como tal no la puedo dar usando la funcion exp, forzosamente tengo que usar la formula con factorial  :(  (aunque aqui esta solo como referencia)

Me gusto mucho este otro código, lo reviso con tiempo. Yo estaba probando a hacerlo por partes para aprender a definir varias funciones y usarlas en main.


La serie es: 1+1x/1 + x^2/ 1*2 + x^3/ 1*2*3 + x^4/1*2*3*4 + .......

Si observas cada nuevo sumando se obtiene del anterior multiplicando por una nueva x y dividiendo por un nuevo numero, que es justo el siguiente del último que se uso. Así la variable frac*x/i+1  irá dando:

i=0        frac=0
i=1        frac=x/1
i=2        frac=x/1 * x/2 = x^2/ 1*2
i=2        frac=x/1 * x/2 * x/3= x^3/ 1*2*3


Y así sucesivamente y la suma de frac dará el desarrollo en serio, Así de simple.

Como aplicación de lo anterior y sin usar exp sino tomando, como tu  habías propuesto, el número de términos:

Código
  1. Teclea el valor de x: 1
  2. Numero de terminos: 3
  3. Valor estimado: 2.666666666666667
  4.  
  5.  
  6. Teclea el valor de x: 10
  7. Numero de terminos: 10
  8. Valor estimado: 12842.30511463845
  9.  
  10.  
  11. Teclea el valor de x: 1000
  12. Numero de terminos: 100
  13. Valor estimado: 1.190420382778621e+142

Código
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(void)
  4. {
  5.     double x, serie=0, frac;
  6.     int i, n;
  7.     while (1)
  8.     {
  9.        serie=1;
  10.        printf("Teclea el valor de x: ");
  11.        scanf("%lf", &x);
  12.        printf(" Numero de terminos: ");
  13.        scanf("%d",&n);
  14.        frac=1;
  15.        for(i=0;i<n;i++)
  16.        {
  17.            frac=frac*x/(i+1);
  18.            serie+=frac;
  19.        }
  20.        printf("\nValor estimado: %1.16g\n\n\n", serie);
  21.     }
  22.    return 0;
  23. }
  24.  

Por lo que respecta al uso de funciones yo soy partidario de usarlas en casos de que se repita una parte del código, por ejemplo si estas calculando números combinatorios  hay  teóricamente que calcular tres factoriales, por lo que en este caso el uso de una función factorial nos evita repetir el código para calcular el mismo tres veces. O bien cuando entre varios se esté haciendo un código y queramos repartir la tarea, cada uno hará su parte como una función. Pero en estos casos tan sencillos me parece más oportuno estrujarse el cerebro buscando formas simples y más eficientes, como habrás visto con el uso de la variable frac.

Saluditos! .... ..
« Última modificación: 7 Junio 2013, 13:35 pm por leosansan » En línea

edr89

Desconectado Desconectado

Mensajes: 105


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #8 en: 7 Junio 2013, 01:49 am »

Gracias!, ya lo entendi, la clave es:

Código
  1. fact*=(x/n++);

y como dices me evito lo demas

Saludos!
En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] e^x, si x es grande, numero negativo
« Respuesta #9 en: 7 Junio 2013, 05:31 am »

Gracias!, ya lo entendi, la clave es:

Código
  1. fact*=(x/n++);

y como dices me evito lo demas


Más exactamente:

Código
  1. frac=frac*x/(i+1);

No confundir con:

Código
  1. frac=frac*x/(i++);

ya que en este caso sólo se tomarían los términos pares de la serie, ya que en cada ciclo del for harían dos incrementos, el del for y el de la instrucción última.

Saluditos desde Gran Canaria! .... ..
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
numero positivo y negativo en C++
Programación C/C++
rub'n 7 85,707 Último mensaje 9 Julio 2010, 00:19 am
por rub'n
[Python] Qué número de los introducidos es el más grande...?
Python
sora_ori 5 5,936 Último mensaje 18 Noviembre 2012, 14:17 pm
por sora_ori
indicar cual es el numero mas grande y pequeño
Programación C/C++
mort 3 10,610 Último mensaje 5 Enero 2015, 02:00 am
por Yoel Alejandro
numero hexadecimal grande
Java
m@o_614 1 1,886 Último mensaje 21 Enero 2015, 07:14 am
por 3n31ch
Leer un numero muy grande
Programación C/C++
mendez1415 1 2,059 Último mensaje 26 Noviembre 2016, 18:07 pm
por engel lex
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines