PHP Function to Compare Floating Point Numbers

September 14th, 2012 - Posted by Steve Marks to PHP, Web Development.

If you’ve found this post you’re probably, like I once did, experiencing problems with comparing floating point numbers in PHP. A section on the official PHP website confirms the difficulty in doing this and why it can be problematic.

And I quote…

As noted in the warning above, testing floating point values for equality is problematic, due to the way that they are represented internally. However, there are ways to make comparisons of floating point values that work around these limitations.

You can read more about comparing float numbers on the PHP website here.

In the same section on the above page is a snippet of code that shows how to compare two floating numbers to 5 digits of precision. In a similar light, and as a result of needing to regularly use floating points in calculations, I decided to write a function that would quickly and easily allow me to check if one floating point number is equal to, greater than, less than, or not equal to another floating point number.

The function can be found below:

// a function for comparing two float numbers
// float 1 - The first number
// float 2 - The number to compare against the first
// operator - The operator. Valid options are =, <=, <, >=, >, <>, eq, lt, lte, gt, gte, ne
function compareFloatNumbers($float1, $float2, $operator='=')
{
	// Check numbers to 5 digits of precision
	$epsilon = 0.00001;
	
	$float1 = (float)$float1;
	$float2 = (float)$float2;
	
	switch ($operator)
	{
		// equal
		case "=":
		case "eq":
		{
			if (abs($float1 - $float2) < $epsilon) {
				return true;
			}
			break;	
		}
		// less than
		case "<":
		case "lt":
		{
			if (abs($float1 - $float2) < $epsilon) {
				return false;
			}
			else
			{
				if ($float1 < $float2) {
					return true;
				}
			}
			break;	
		}
		// less than or equal
		case "<=":
		case "lte":
		{
			if (compareFloatNumbers($float1, $float2, '<') || compareFloatNumbers($float1, $float2, '=')) {
				return true;
			}
			break;	
		}
		// greater than
		case ">":
		case "gt":
		{
			if (abs($float1 - $float2) < $epsilon) {
				return false;
			}
			else
			{
				if ($float1 > $float2) {
					return true;
				}
			}
			break;	
		}
		// greater than or equal
		case ">=":
		case "gte":
		{
			if (compareFloatNumbers($float1, $float2, '>') || compareFloatNumbers($float1, $float2, '=')) {
				return true;
			}
			break;	
		}
		case "<>":
		case "!=":
		case "ne":
		{
			if (abs($float1 - $float2) > $epsilon) {
				return true;
			}
			break;	
		}
		default:
		{
			die("Unknown operator '".$operator."' in compareFloatNumbers()");	
		}
	}
	
	return false;
}

Simply pass the two numbers you wish to compare, as well as the operator, and the function will return TRUE or FALSE based on if the case is true or not.

Tags: ,
This entry was posted on Friday, September 14th, 2012 at 8:29 pm by +Steve Marks and is filed under PHP, Web Development. You can follow any responses to this entry through the RSS 2.0 feed.
Comments...

Fear not, we won't publish this

Comments (1)
  1. Chris says:

    Thanks a million. Hopefully we will see some advancement in this area in ver. 7!