2010-12-06 19 views
8

Tengo el siguiente código muy simple -una simple pregunta acerca de fundición enteros en C++

int x=15000 
int z=0.7*x 
cout<<"z = "<<z<<endl; 

consigo la salida

z=10499 

pero si lo cambio a

int z=0.7*15000 
cout<<"z = "<<z<<endl; 

salidas

z=10500 

entiendo que tiene algo que ver con z lanzando el resultado a int , pero ¿por qué es diferente en ambos casos?

gracias,

Edición - estoy usando Ubuntu 10.10 de GCC construir

+0

Tengo 10500 (gcc 4.2) ... ¿qué compilador estás usando? ¿Es exactamente el código que tienes? – Vladimir

Respuesta

4

int z = 0,7 * x;

El valor de doble precisión 0.7 no es exactamente representable como un número de coma flotante; su representación hexadecimal es 3fe6666666666666 en la mayoría de las máquinas, que es menor que el valor verdadero 3fe6666666666666 ... Por lo tanto, el resultado de doble precisión de 0.7 * x es menor que su valor real y se redondea hacia abajo. Este es el comportamiento correcto.

int z = 0.7 * 15000;

El compilador, por otra parte, es lo suficientemente inteligente como para ver que 0.7 * 15000 es representable exactamente como 7 * 1500 = 10500. Por lo tanto, utiliza el resultado correcto, en lugar del resultado obtenido al compilar la expresión y ejecutarlo.

6

supongo que es por el compilador, que simplifica expresiones aritméticas en el tiempo de compilación.

La primera expresión se calculó usando FPU (con precisión finita), y la segunda: por preprocesador (con precisión "infinita"). Intente ejecutar el programa en modo de lanzamiento (o con -O2), los resultados deberían ser los mismos para ambas expresiones.

3

Creo que ruslik tiene la respuesta correcta a tu pregunta.

Simplemente agregaría: siempre mantenga sus cálculos en flotación o en doble hasta el último momento. De esa forma no pierdes precisión.

trate de cambiar su código para esto:

double z = 0.7 * 15000.0; 
cout<<"z = "<<z<<endl; // Will need to include some formatting 

o

int z = (int) (0.7 * 15000.0); 
cout<<"z = "<<z<<endl; 
+1

Ambas sugerencias no son operativas, y no hacen nada para resolver el problema. – TonyK

+0

El problema es que 0.7 * x da un resultado diferente a 0.7 * 15000. Ver mi respuesta a continuación/arriba. – TonyK

+1

Creo que este es un buen consejo. Si necesita doble precisión, mantenga sus variables en dobles. Use el redondeo como último paso, si es necesario. –

Cuestiones relacionadas