2010-11-08 11 views
6

Duplicar posible:
PHP Math Precision((171.36/1.19) == 144) es falso?

Aquí es un ejemplo de código en PHP

echo (171.36/1.19) 
//[PHP] result: 144 
//[JavaScript] result: 144.00000000000003 
//[Manual] result : 144 

$var1 = 144; 
$converted = 171.36/1.19 


//Variable 1 is less than Converted? 
echo (($var1 < $converted)?"Yes":"No") 
//result: Yes 

//Variable 1 is equal to Converted? 
echo (($var1 == $converted)?"Yes":"No") 
//result: No 

echo (($converted == 144)?"Yes":"No") //--> NO 
echo (("144.00" == 144)?"Yes":"No") //--> YES 

¿Me podría dar una explicación sencilla/respuesta y dime que PHP no es calesa.

+25

La radiación ionizante puede causar que una CPU produzca un resultado incorrecto. Guardo una botella de píldoras de yodo en mi escritorio, y tomo 2 cada vez que falla una prueba de igualdad de coma flotante. – mikerobi

+2

¿Pensé que se suponía que debías tomar 2,1 pastillas? ¿Qué pasa con la disparidad? – webbiedave

Respuesta

16

Este es el resultado de cálculos de punto flotante que implican inherentemente una cierta cantidad de error. Los números reales arbitrarios no pueden almacenarse con precisión en el formato de punto flotante utilizado por la mayoría de los lenguajes (incluido PHP). Verá resultados similares en muchos otros idiomas.

http://php.net/manual/en/language.types.float.php (leer el cuadro rosado grande)

+1

+1 Probablemente la mejor respuesta del grupo, ya que incluso se refiere al manual de PHP. – cgp

+0

Estoy de acuerdo; +1 para apuntar al manual de PHP, lo que explica este desafortunado malentendido común. – Randolpho

19

Está viendo que el resultado es lo suficientemente cerca de 144 que ese es el valor que se muestra cuando lo convierte en una cadena, pero es no exactamente 144, razón por la cual obtiene "NO" en la penúltima línea .

Este es el mismo problema con los números de coma flotante que la gente ejecuta una y otra vez.

Ni 171.36 ni 1.19 pueden representarse exactamente en tipos de coma flotante binarios. Entonces PHP usa una aproximación muy cercana a ellos. Cuando realiza operaciones aritméticas, el resultado será tan preciso como sea posible, dadas las limitaciones de los tipos de datos implicados y en los datos originales (es decir, "no exactamente" como esperaba).

Conclusión: no compare valores de coma flotante para igualdad directamente, excepto en circunstancias muy especiales. Por lo general, es mejor probarlos dentro de una cierta tolerancia (por ejemplo, es el valor entre 144-0.00001 y 144 + 0.00001).

+0

[Flash de noticias: los números de coma flotante no son infinitamente precisos. Detalles a las 10: 05000000004.] (Http://twitter.com/CrystalEmpGames/status/27160772411) –

1

PHP no tiene errores. Muestra 144 solo porque redondea a 12 cifras significativas al convertir el número de punto de flotación en una cuerda para imprimir.

Si imprime el número a 17 decimales, verá que el resultado es de hecho 144.00000000000003, lo mismo que el resultado de Javascript.

(Las otras respuestas han explicado por qué el resultado no es exactamente 144 ya, no voy a repetir aquí.)

Ver http://www.ideone.com/u0yB8 de código de ejemplo.

5

De The Floating-Point Guide:

¿Por qué mis números, como 0,1 + 0,2 suman a una buena ronda 0,3, y en su lugar me siento un extraño> resultado como ,30000000000000004?

Dado que internamente, las computadoras usan un formato (punto flotante binario) que no puede con precisión representan un número como 0.1, 0.2 o 0.3 en absoluto.

Cuando se compila o interpreta el código, su "0.1" ya está redondeado al número más cercano en ese formato, lo que da como resultado un pequeño error de redondeo incluso antes de que ocurra el cálculo.

Básicamente, cuando se escribe el literal 171.36 en su código y el código se interpreta, el número del equipo va a utilizar no es, de hecho, 171.36 - por lo que no es sorpresa que daría un resultado diferente cuando se usa en un cálculo.

Cuestiones relacionadas