salida extraña en comparación de float con float literal

salida extraña en comparación de float con float literal

Esto sucede porque en su declaración

  if(f == 0.7)

el 0.7 se trata como un doble. Prueba 0.7f para asegurarte de que el valor se trata como flotante:

  if(f == 0.7f)

Pero como sugirió Michael en los comentarios a continuación, nunca debe probar la igualdad exacta de los valores de punto flotante.


Esta respuesta para complementar las existentes:tenga en cuenta que 0.7 no se puede representar exactamente como un flotador (o como un doble). Si se representara exactamente, entonces no habría pérdida de información al convertir a flotante y luego volver a duplicar, y no tendría este problema.

Incluso se podría argumentar que debería haber una advertencia del compilador para las constantes de punto flotante literal que no se pueden representar exactamente, especialmente cuando el estándar es tan confuso con respecto a si el redondeo se realizará en tiempo de ejecución en el modo que se ha establecido como ese momento o en tiempo de compilación en otro modo de redondeo.

Todos los números no enteros que se pueden representar exactamente tienen 5 como su último dígito decimal. Desafortunadamente, lo contrario no es cierto:algunos números tienen 5 como su último dígito decimal y no se puede representar exactamente. Todos los enteros pequeños se pueden representar exactamente, y la división por una potencia de 2 transforma un número que se puede representar en otro que se puede representar, siempre que no entres en el reino de los números desnormalizados.


En primer lugar, miremos dentro del número flotante. Tomo 0.1f tiene 4 bytes de largo (binary32), en hexadecimal es
CD CC CC 3D .
Por el estándar IEEE 754 para convertirlo a decimal debemos hacer así:


En binario 3D CC CC CD es
0 01111011 1001100 11001100 11001101
aquí el primer dígito es un bit de signo. 0 significa (-1)^0 que nuestro número es positivo.
Los segundos 8 bits son un exponente. En binario es 01111011 - en decimal 123. Pero el Exponente real es 123-127 (siempre 127)=-4 , significa que necesitamos multiplicar el número que obtendremos por 2^ (-4).
Los últimos 23 bytes son la precisión Significando. Ahí el primer bit lo multiplicamos por 1/ (2^1) (0.5), el segundo por 1/ (2^2) (0.25) y así sucesivamente. Aquí lo que obtenemos:


Necesitamos sumar todos los números (potencia de 2) y sumarle 1 (siempre 1, por estándar). Está
1,60000002384185791015625
Ahora multipliquemos este número por 2^ (-4), es de Exponent. Simplemente dividimos el número de arriba por 2 cuatro veces:
0,100000001490116119384765625
Usé la calculadora MS


**

Ahora la segunda parte. Conversión de decimal a binario.

**
tomo el numero 0.1
Es fácil porque no hay parte entera. Primer bit de signo:es 0. Calcularé ahora la precisión exponencial y significativa. La lógica es multiplicar por 2 números enteros (0.1*2=0.2) y si es mayor que 1 restar y continuar.

Y el número es .00011001100110011001100110011, estándar dice que debemos cambiar a la izquierda antes de obtener 1. (algo). Como ves necesitamos 4 turnos, a partir de este número calculamos Exponente (127-4=123 ). Y la precisión de Significand ahora es
10011001100110011001100 (y hay bits perdidos).
Ahora el número entero. Bit de signo 0 El exponente es 123 (01111011 ) y la precisión significativa es 10011001100110011001100 y todo es
00111101110011001100110011001100 vamos a compararlo con los que tenemos del capitulo anterior
00111101110011001100110011001101
Como ves, los últimos bits no son iguales. Es porque trunco ​​el número. La CPU y el compilador saben que hay algo después de que la precisión de Significand no se pueda mantener y simplemente establecen el último bit en 1.