Mala
Mala

Reputation: 14843

Somehow 1 does not equal 1 (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?

Upvotes: 6

Views: 449

Answers (3)

lc.
lc.

Reputation: 116528

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).

Upvotes: 4

Quillion
Quillion

Reputation: 6476

Cast to int doing

if ((int)$total == 1)

And it will work :)

EDIT: or even better

$total = (int)array_sum($array);

Upvotes: 1

Jordan
Jordan

Reputation: 1433

Floats in php (and other languages) are not precise, therefore (float)1 might actually be 1.00000000000000123113 or .99999999999999823477

See answer PHP - Floating Number Precision for more information

Upvotes: 2

Related Questions