Cálculo matemático simple PHP

me puede ayudar a ver este cálculo? Supongo que echo "igual" ... pero me da "no igual"

<?php
$tl_pax = 1;
$ct_pax = 2;
$at_pax = 2;

$a = 0.5;
$b = 0.2;
$c = 0.2;
$d = 0.2;
$e = 0.2;
$f = 0.2;
$g = 0.2;
$h = 0.9;

$sum = $a + $b + $c + $d + ($e * $tl_pax) + ($f * $ct_pax) + ($g * $at_pax) + $h;

$total = 3;

if($total == $sum){
    echo 'equal: ' . $sum . ' - ' . $total;
}
else{
    echo 'not equal: ' . $sum . ' - ' . $total;
}
?>

preguntado el 27 de agosto de 11 a las 18:08

¿Cuál es la salida para la suma y el total? -

5 Respuestas

Este es el caso habitual del error de redondeo asociado con los números de coma flotante binarios. Hay números que no se pueden representar exactamente en binario y, por lo tanto, el resultado será de algún margen. Para leerlo, el artículo de wikipedia sobre Números de punto flotante es genial.

El patrón habitual que se encuentra en este caso es elegir un delta y compararlo:

 if(abs($total - $sum) < 0.01)
   echo "equal";

Tendrá que elegir su delta de forma adecuada según el caso de uso.

Respondido 27 ago 11, 22:08

Tal vez deberías hacer eso if(abs($total - $sum) < 0.01) - Medo42

Compruebe si tienen una diferencia inferior a 0.00001

if(abs($total - $sum) < 0.00001){

http://sandbox.phpcode.eu/g/56905/6

Este artículo le muestra por qué sucede esto

Respondido 27 ago 11, 22:08

Pierde la credibilidad de decir igual (realmente podría no ser igual). - Vadiklk

pero entonces no son necesariamente iguales. - Fantasma de Madara

@Rikudo Second ... Estoy buscando una mejor solución - génesis

@Bart no, no lo haría ... Presione F5 - génesis

Está bien, eso es correcto, pero ahora acabas de copiar lo que 4 personas antes recomendaban ... - Bart Kiers

Es porque su suma es realmente algo así como 2.9999999999999999999, debido a la aritmética de pont flotante. PHP simplemente se lo oculta cuando lo imprime. Vea el ejemplo en floor((0.1+0.7)*10) aquí: http://php.net/manual/en/language.types.float.php

Nunca debe comparar un número de punto flotante para determinar la igualdad. La forma correcta de comparar flotantes es usar un rango como:

if($total-0.0000001 <= $sum && $sum <= $total+0.0000001){

Puedes verlo en acción aqui: http://codepad.org/kaVXM5g0

Esa línea solo significa que $ total debe estar dentro de 0.0000001 de $ suma para ser considerado igual. Puede elegir el número usted mismo, dependiendo de la precisión que necesite.

Alternativamente, puede simplemente redondear $sum en este caso, pero básicamente estás haciendo lo mismo solo con un rango de 2.5 - 3.499... en lugar de 2.9999999 - 3.0000001

Respondido 27 ago 11, 22:08

La diferencia se debe a los límites de la precisión del punto flotante.

Los valores como 0.9 (9/10) no se pueden escribir exactamente como números de coma flotante binarios, al igual que 0.3333 ... (1/3) no se pueden escribir exactamente como una fracción decimal. Esto significa que, por ejemplo, $ h tiene una representación redondeada inexacta de 0.9. Como resultado, su cálculo arroja algo muy cercano a 3, pero no exactamente 3.

Respondido 27 ago 11, 22:08

Los flotadores son malvados.

Cita de http://php.net/float

"Por lo tanto, nunca confíe en los resultados de los números flotantes hasta el último dígito, y nunca compare los números de punto flotante para determinar la igualdad. Si se necesita una mayor precisión, las funciones matemáticas de precisión arbitraria y las funciones gmp están disponibles".

Respondido 27 ago 11, 22:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.