sbuck
sbuck

Reputation: 1864

Figure out why this simple comparison is showing not equal in PHP

I put a check in a script that makes sure a total is correct. What it does is looks at the total as it is stored in the database and then using other variables, calculates what the total should be.

If these two values - the stored total and the calculated total - are not equal, it's a problem so I want it to send an email alert.

Here's the snippet of the code I use to do this:

$storedTotal     = $row['total']; # Pulls from a varchar field in the database
$calculatedTotal = $subtotal + $tax + $shipping - $deduct;

# Make sure the stored total equals what it should (the calculated total)
if($storedTotal != $calculatedTotal) {
    # Send an alert
    mail("[email protected]","Total check fail","Stored total:$storedTotal \n\n Calculated total:$calculatedTotal \n\n");
}

It seems very simple, however, I repeatedly get emails from it that looks like this:

Stored total:23.40

Calculated total:23.40

As you can see, the two values appear the same.

Can anyone see any reason why they're not showing as equal? I'm not using a strict equality check so it shouldn't be getting tripped up on types.

Upvotes: 1

Views: 282

Answers (4)

Reputation:

I had the same problem - my simple data-consistency sanity checks were failing as a result. I used Alnitak's solution to implement this simple function:

function not_equals($val1, $val2)
{
    return (abs($val1 - $val2) > 0.001);
}

Now my tests pass but I'm very unhappy. A programming language where 6.60 does not equal 6.60??? What else will PHP do to me? I want to go back to C++!

Upvotes: 0

scronide
scronide

Reputation: 12248

Try converting and rounding before you compare them:

$storedTotal        = round(floatval($storedTotal), 2);
$calculatedTotal    = round(floatval($calculatedTotal), 2);

if ($storedTotal != calculatedTotal) {
...

Upvotes: 2

Alnitak
Alnitak

Reputation: 340045

It's most likely a floating point comparison error - there are probably some very insignificant digits which the default float -> string conversion routines think aren't worth printing but which are significant enough to cause the comparison to fail. You'll find dozens of similar questions on StackOverflow.

As these appear to be currency amounts, just check that they're within a tenth of a minor unit of each other:

$is_equal = (abs($val1 - $val) < 0.001);

Upvotes: 11

&#211;lafur Waage
&#211;lafur Waage

Reputation: 70011

There must be something else that you are missing and we aren't seeing. Probably something related to the size of floats.

Because.

$test = "24.50";
$test2 = 24.50;

var_dump($test == $test2); // bool(true)

Upvotes: -2

Related Questions