Ian
Ian

Reputation: 202

Why does this value obtained from floatval() evaluate to false when compared against another number?

See the test case below:

$val = floatval("336.00");
$result = 300*1.12;

header("content-type: text/plain");

echo "\$result = 300*1.12 which equals $result\n";
echo "\$val = floatval(\"336.00\") which equals $val\n";
echo "gettype(\$val) = ".gettype($val)."\n";
echo "gettype(\$result) = ".gettype($result)."\n";
echo "gettype(300*1.12) = ".gettype(300*1.12)."\n";
echo "gettype(floatval(\$result)) = ".gettype(floatval($result))."\n";

if ($result == 300*1.12) 
    echo "\$result == 300*1.12 is true\n";
else
    echo "\$result == 300*1.12 is false\n";

if ($result == $val) 
    echo "(\$result == \$val) \$result == 300*1.12 is true\n";
else
    echo "(\$result == \$val) \$result == 300*1.12 is false\n";

You'd think that the last if/else block would also show true, right? Not so! See the output from the same script:

$result = 300*1.12 which equals 336
$val = floatval("336.00") which equals 336
gettype($val) = double
gettype($result) = double
gettype(300*1.12) = double
gettype(floatval($result)) = double
$result == 300*1.12 is true
($result == $val) $result == 300*1.12 is false

What am I missing here? I've tried it on various version of PHP 5+ and they all produce the same output.

Upvotes: 2

Views: 1343

Answers (2)

Czechnology
Czechnology

Reputation: 15012

If you read some about the floating-point arithmetic, you'll see that there's often a small error made during each operation. That means you cannot compare two float values for equality

$a == $b;

You can however check if the error is small enough for a particular precision:

abs($a - $b) < $eps;

$eps is dependant on the system you're using, you can read more about it on Wiki. Of course, this only applies for one arithmetic operation. After performing several operations, you need to scale the epsilon appropriately.

Upvotes: 1

Related Questions