Foros del Web » Programación para mayores de 30 ;) » C/C++ »

duda sobre float y sacar constante e

Estas en el tema de duda sobre float y sacar constante e en el foro de C/C++ en Foros del Web. Hola, creo que es la tercera vez que hago una pregunta en un periodo de tiempo tan breve en este foro, pero no tengo a ...
  #1 (permalink)  
Antiguo 17/02/2015, 21:58
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 2 meses
Puntos: 0
duda sobre float y sacar constante e

Hola, creo que es la tercera vez que hago una pregunta en un periodo de tiempo tan breve en este foro, pero no tengo a nadie mas a quien preguntar , sorry.
Bueno para empezar tengo 2 dudas que están relacionadas entre si, estoy estudiando el libro de deitel y estoy truncado en los dos últimos ejercicios del capitulo 3, es sobre sacar el valor aproximado de la constante "e" mediante la siguiente formula e = 1 + 1/1! + 1/2! + 1/3!...
Hice el programa pero no me devuelve ningún valor, se queda la pantalla vacía lo que me da a entender que se ha creado un ciclo infinito, pero no he dado con el error:

Código:
#include <stdio.h>

int main ()
{
	
	float ni = 1;       //es el factorial !n
	float e = 1;        // valor de "e"
	float contador = 2;   //contador lo incie en 2
	float n = 2;       
	
	e += 1/ni;          //aqui "e" vale 2
	++ni;
	
	while (e != 2.718055556){
		while (n != 1){
			ni  = ni * (n-1);
			--n;
		}
		++contador;
		n = contador;  //lo que hago es darle el valor de contador a "n"
		e += 1/ni;
		++ni;
	}
	
	printf("%f\n", e);
	
	system("pause");
	return 0;
}
Bueno aqui al principio el "contador" vale lo mismo que "n" porque en el ciclo el valor de n se pierde al restarse , y por lo tanto contador reserva el valor original y le suma 1, para luego almacenarse de nuevo en "n" y comenzar el siguiente ciclo con el factorial que sigue.
Me termina dando ciclo infinito siendo que se supone que al llegar al factorial de 7 el valor de "e" seria 2.718055556, y el ciclo se debería de romper, y desplegarme el valor de e.
Bueno la otra duda es sobre float y surgio cuando quise sacar el valor de "e", sin usar ciclos:
Código:
#include <stdio.h>

int main (){
	
	float e;
	
	e = 1 + 1 + (1/2) + (1/6) + (1/24) + (1/120);
	
	printf("%f\n", e);
	
	return 0;
		
	
	
}
No me despliega los decimales del numero "e" sino 2.00000, lo que me da a entender que si el primer programa funcionara me daria el mismo resultado.
Por cierto no puedo usar otro tipo de variable de mas extensión.
  #2 (permalink)  
Antiguo 17/02/2015, 23:31
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: duda sobre float y sacar constante e

Hola; te comento algunas cosas que no están bien.

Código:
float ni = 1;       //es el factorial !n
Estás inicializando la variable de tipo float con un 1, que es entero. El compilador lo va a "castear" a float de todos modos, pero en general conviene ser explícito, para evitar errores. Entonces, conviene:
Código:
float ni = 1.0f; // la f indica que 1.0 es de tipo float, si no se pone sería un double.
Pero, por otro lado, si ni va a guardar el resultado de calcular un factoria, y un factorial es un número entero, no hay razón para que la variable sea de tipo float. Debería ser
Código:
int ni = 1;
Código:
float n = 2;
n es otra de las variables que no deberían ser de tipo float.

Otra:
Código:
e += 1/ni;          //aqui "e" vale 2
Aquí 1 es un int, que dividido por cualquier otro entero mayor que 1 va a dar 0 (división entera). En la primera ocurrencia no hay problema porque ni vale 1, pero en la segunda, dentro del segundo bucle while, deberías poner
Código:
e += 1.0f/ni;
para que se puedan ir incrementando en partes fraccionarias. Otra vez, 1.0f es una constante de tipo float.

Código:
while (e != 2.718055556){
Probablemente esta desigualdad va a resultar true eternamente. Por causa de la forma en que se representan los números float o double, nunca deberían compararse de esa manera. En este caso, creo que podría ser suficiente
Código:
while (e <= 2.718055556){
Hay una explicación completa en
http://www.parashift.com/c++-faq/flo...int-arith.html

Y por último, la serie que tienes es muy lentamente convergente, por lo que vas a necesitar unos cuantos miles de millones de ciclos para llegar a un valor aproximado de e como el que pretendes.
  #3 (permalink)  
Antiguo 18/02/2015, 01:12
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: duda sobre float y sacar constante e

Una pequeña correción lareto:

Cita:
Iniciado por lareto Ver Mensaje
Otra:
Código:
e += 1/ni;          //aqui "e" vale 2
Aquí 1 es un int, que dividido por cualquier otro entero mayor que 1 va a dar 0 (división entera).
Dado que en su versión, "ni" es de tipo float, el programa va a castear ese "1" a float, por lo que la división va a ser correcta.

Cita:
Iniciado por lareto Ver Mensaje
Código:
while (e != 2.718055556){
Probablemente esta desigualdad va a resultar true eternamente. Por causa de la forma en que se representan los números float o double, nunca deberían compararse de esa manera. En este caso, creo que podría ser suficiente
Código:
while (e <= 2.718055556){
Hay una explicación completa en
http://www.parashift.com/c++-faq/flo...int-arith.html
Tampoco es una forma correcta de hacer una comparación de dos float. En primer lugar, float tiene 6 dígitos significativos, el resto puedes considerarlos tranquilamente basura. Es el precio que hay que pagar a cambio de la posibilidad de manejar números grandes.

En el caso de los float, desde mi punto de vista, la forma correcta de realizar una comparación es algo tal que:

Código C++:
Ver original
  1. while ( e - 2.718055 < 1e-5 )

El motivo es que, como ha dicho lareto, las representaciones binarias de los números decimales no son todo lo precisas que nos gustaría, por lo que forzar una equivalencia 1=1 puede dar problemas en el momento en el que empiezan a entrar en acción los decimales.

La forma que propongo tiene como ventaja la flexibilidad. Puesto que las representaciones decimales están sujetas a errores de precisión, este mecanismo de comparación trata de camuflar el problema dando resultados bastante satisfactorios.
  #4 (permalink)  
Antiguo 18/02/2015, 22:02
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 2 meses
Puntos: 0
Respuesta: duda sobre float y sacar constante e

Bueno mas o menos entiendo, intente hacerlo de otra forma, para comprobar el valor de "e" constantemente:
Código:
#include <stdio.h>

int main ()
{
	
	int ni = 1;       //es el factorial !n
	float e = 1;        // valor de "e"
	int contador = 2;   //contador lo incie en 2
	int n = 2; 
	
	printf("%f\n", e);      
	
	e += (float)1/ni;          //aqui "e" vale 2
	++ni;
	
	printf("%f\n", e);
	
	while (e <= 2.7){
		while  (n != 1){
			ni  = ni * (n-1);
			--n;
		}
		++contador;
		n = contador;  //lo que hago es darle el valor de contador a "n"
		e += (float)1/ni;
		++ni;
		printf("%f\n", e);
	}
	
	printf("%f\n", e);
	printf("Fin\n");
	
	system("pause");
	return 0;
}
el resultado me da:

1.000000
2.000000
2.500000
2.666667
2.690476
2.691445
2.691453 Este resultado se repite como 20 veces mas.
y los dos últimos me dan:
1.#INF00
1.#INF00
Fin

Entonces el resultado que mas se acerca a "e" seria 2.691453?
El valor de e?
Código:
while ( e - 2.718055 < 1e-5 )
¿Por cierto el "1e-5" a que se refiere?
  #5 (permalink)  
Antiguo 19/02/2015, 00:17
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: duda sobre float y sacar constante e

1.#INF00 es la forma en que tiene tu compilador de decirte que el número que estás calculando es demasiado grande para poder ser representado como float.

Hay un error en la forma de calcular el factorial. Te paso una función que lo hace mejor:
Código C:
Ver original
  1. unsigned int factorial(int n)
  2. {
  3.     int contador;
  4.     int fact = 1;
  5.     for (int contador = 1; contador <= n; contador++) {
  6.         fact = fact * contador;
  7.     }
  8.     return fact;
  9. }

Cita:
¿Por cierto el "1e-5" a que se refiere?
se llama "notación exponencial" o "notación científica", y es una forma de decir 1x10^(-5), o sea: 0.00001
(https://es.wikipedia.org/wiki/Notaci...ient%C3%ADfica)

Etiquetas: constante, dado, float, funcion, int, numero, programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:18.