¿Por qué el control va en la parte “else”?

Posible duplicado:
La forma más efectiva de flotación y doble comparación.
Salida extraña en comparación de float con float literal

int main() { float a = 0.8; if (a == 0.8) printf("x\n"); else printf("y\n"); return 0; } 

Aunque a es igual a 0,8 , genera y.

0.8 no se puede representar con precisión en punto flotante binario. Su código if (a == 0.8) básicamente compara 0.8 de precisión simple con 0.8 de precisión doble, que no son iguales.

Para ver esto por ti mismo, prueba el siguiente código:

 int main() { double a = 0.8f; double b = 0.8; printf("%lX\n", *(long *)&a); printf("%lX\n", *(long *)&b); } 

Produce:

 3FE99999A0000000 3FE999999999999A 
 if (a==0.8f) 

Intenta esto en su lugar. Por defecto, se considera que el tipo es doble, lo que tiene un error de precisión en comparación.

Estás usando un literal, 0.8, pero eso no significa necesariamente que sea un flotador. intenta usar:

 if (a==0.8F) 

en lugar

Además, la representación de partes fraccionarias de números es notoriamente propensa a errores, debido a que las computadoras utilizan internamente la base-2.

Los números de punto flotante no son valores exactos. No debes compararlos usando == y! =. Use operadores mayores que y menos que con un épsilon razonablemente pequeño:

 if ((a > 0.79) && (a < 0.81)) 

Esto se debe a que los puntos flotantes no pueden representar exactamente decimales, por lo que no es exactamente 0,8. Y estás comparando 0.8 redondeado como un flotador a 0.8 redondeado como un decimal, que no son necesariamente lo mismo.

Los flotadores no siempre son 100% exactos, no pueden ser por la forma en que están almacenados. Si dices float a = 0.8 , realmente podría ser 0.800000000001 o algo así. Para compensar esto, debe utilizar algún tipo de umbral. prueba if (fabs(a-0.8) < 1.0e-5) lugar

porque para los números de punto flotante 0.8 realmente no significa 0.8 pero es 0.799999999 por lo que sucede Por qué es 0.79999999
Esto depende del almacenamiento de un valor flotante. Los valores decimales se almacenarán en forma binaria (…., 2 ^ 3,2 ^ 2,2 ^ 1,2 ^ 0,., 2 ^ -1,2 ^ -2,2 ^ -3, .. .)

Entonces, cuando 0.8 se almacena en múltiplos de 2 como .101b (que no es 0.8 sino 0.799999988). Por lo tanto, su valor será menor que 0.8.

 if (a > 0.8) 

También es False por eso.

para su resultado intente

 if (a == 0.8f) 

Estás comparando 2 valores de diferentes tipos: a es de tipo float , 0.8 es de tipo double .

antes de la comparación, el valor float se convierte a double … pero la conversión de double a float y viceversa no necesariamente produce el mismo valor

 if (0.8 == (double)(float)0.8) /* ... */