Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Somehow 1 does not equal 1 (PHP)

Tags:

equality

php

I have an associative array whose values are floats, which are supposed to be probabilities. As such, I sum them up and require that the result is in fact 1.

$total = array_sum($array);
echo '$total = '.$total."\n";
if ($total == 1) {
    die("total is 1");
} else {
    die("total is not 1");
}

This mysteriously outputs:

$total = 1
total is not 1

Doing a var_dump($total) yields float(1), and yet even $total == (float)1 returns false.

What's going on?

like image 284
Mala Avatar asked Sep 06 '13 17:09

Mala


1 Answers

Floating point values are by nature imprecise and are very rarely equal to one another due to the way they are stored and rounding errors. You should be comparing floats by seeing if the two values are "close enough". That is, comparing the absolute value of the difference between the two values to a significantly small margin of error (often referred to as "epsilon").

One such implementation may be:

if (abs($total - 1) < 0.000000001)
    die("total is 1");
} else {
    die("total is not 1");
}

Note that only your application's requirements can truly determine what a safe margin of error is and at what point numbers should be rounded for display.


If you are dealing with currency values, for example, and require exact precision, a better solution would be to forgo floating-point arithmetic entirely. One option in this case would be to use an integer type and store the number as cents, dividing only at the last minute to display the number to the user (or not even dividing, and injecting a decimal point into the string instead).

like image 109
lc. Avatar answered Nov 06 '22 07:11

lc.