//, PHP/Floating Point Comparisons In PHP and Javascript

Floating Point Comparisons In PHP and Javascript

Beware Comparing Floating Point Values Can Be Hazardous!

The curse of the .0000000001 and .9999999999!”

Here’s the problem. Say you’re comparing two floating point numbers
a (71.00) and b (71.00) to see if they are the same. The problem is if
you’ve done any calculations to arrive at these numbers they might
actually be stored as 71.00000000001. Now if one of them is stored that
way and the other isn’t and you compare the two to see if they are
equal you’ll get a FALSE as the response, even though they should be
the same.

This isn’t a bug, it’s how floating point comparisons are designed
to work. It makes it so people writing complex software that requires
floating point arithmetic can do what they need to. Unfortunately for
the rest of us that usually are just using floating point numbers to
represent things like currency (dollars in my case) it really makes
life difficult!

PHP Floating Point Comparison Made Easy

Here’s my php function that compares floating point numbers:

function moneycomp($a,$comp,$b,$decimals=2) {
$res = bccomp($a,$b,$decimals); // php function for comparing floating point numbers with a specified level of precision
switch ($comp) {
case ">":
return ($res==1);
case ">=":
return ($res==1 || $res==0);
case "<":
return ($res==-1);
case "<=":
return ($res==-1 || $res==0);
default:
case "==":
return ($res==0);
}
}

// example usage: if ($total > $payments) ...
if (moneycomp($total,'>',$payments)) ...

// example usage: if ($debt <= $income) ...
if (moneycomp($debt,'<=',$income) ...

// example usage: if ($cost == $price) ...
if (moneycomp($cost,'==',$price) ...

So that makes life really simple. You just write your comparisons wrapped in the moneycomp() function.

Javascript Floating Point Comparison Made Easy

And here’s my javascript function that compares floating point numbers:

function moneycomp(a,comp,b,decimals) {
if (!decimals)
decimals = 2;
var multiplier = Math.pow(10,decimals);
a = Math.round(a * multiplier); // multiply to do integer comparison instead of floating point
b = Math.round(b * multiplier);
switch (comp) {
case ">":
return (a > b);
case ">=":
return (a >= b);
case "<":
return (a < b);
case "<=":
return (a <= b);
case "==":
return (a == b);
}
return null;
}

// example usage: if (total > payments) ...
if (moneycomp(total,'>',payments)) ...

// example usage: if (debt <= income) ...
if (moneycomp(debt,'<=',income) ...

// example usage: if (cost == price) ...
if (moneycomp(cost,'==',price) ...

Resources And Further Reading

2010-05-25T22:45:59+00:00 January 8th, 2008|JavaScript, PHP|0 Comments

About the Author:

Justin is the chief software architect for MerchantOS, a company that provides web based point of sale and inventory control to small retailers.

Leave A Comment