Makebeta

Web Developer Tools and Tutorials

Floating Point Comparisons In PHP and Javascript

September 14th, 2007 · 4 Comments

I just had to make a quick post about this. Hopefully it will save someone the trouble I’ve been through!

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

Thanks for visiting. Stay tuned, I’m about to release a cool SEO tool I’ve been working on and using =).

Tags: php

Makebeta is community resource produced by MerchantOS. MerchantOS is Point of Sale Software that makes running your retail business easy by organizing your sales and inventory. There's no software to install and data backups are automatic. Get your point of sale and inventory control the easy way with MerchantOS.

4 responses so far ↓

  • 1 Floating Point Comparisons In PHP and… — Advertisement Methods // Oct 1, 2007 at 8:32 am

    [...] Point Comparison Made Easy Heres my php function that compares floating point numbers source: Floating Point Comparisons In PHP and…, Makebeta Web Developer Tools and [...]

  • 2 Keilaron // Nov 20, 2007 at 12:19 pm

    …? Why not just round/floor to x decimals first?

  • 3 justin // Nov 20, 2007 at 12:24 pm

    Because that will return another floating point value which could have the same problem.

  • 4 justin // Nov 20, 2007 at 12:26 pm

    Keilaron, that may work in Javascript I haven’t tested it, but that’s insuficient in PHP - you need to use bccomp.

Leave a Comment