Monday 16 July 2018

PHP Function to Compare Floating Point Numbers

PHP Function to Compare Floating Point Numbers

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:
  1. // a function for comparing two float numbers  
  2. // float 1 - The first number  
  3. // float 2 - The number to compare against the first  
  4. // operator - The operator. Valid options are =, <=, <, >=, >, <>, eq, lt, lte, gt, gte, ne  
  5. function compareFloatNumbers($float1$float2$operator='=')  
  6. {  
  7.     // Check numbers to 5 digits of precision  
  8.     $epsilon = 0.00001;  
  9.       
  10.     $float1 = (float)$float1;  
  11.     $float2 = (float)$float2;  
  12.       
  13.     switch ($operator)  
  14.     {  
  15.         // equal  
  16.         case "=":  
  17.         case "eq":  
  18.         {  
  19.             if (abs($float1 - $float2) < $epsilon) {  
  20.                 return true;  
  21.             }  
  22.             break;    
  23.         }  
  24.         // less than  
  25.         case "<":  
  26.         case "lt":  
  27.         {  
  28.             if (abs($float1 - $float2) < $epsilon) {  
  29.                 return false;  
  30.             }  
  31.             else  
  32.             {  
  33.                 if ($float1 < $float2) {  
  34.                     return true;  
  35.                 }  
  36.             }  
  37.             break;    
  38.         }  
  39.         // less than or equal  
  40.         case "<=":  
  41.         case "lte":  
  42.         {  
  43.             if (compareFloatNumbers($float1$float2'<') || compareFloatNumbers($float1$float2'=')) {  
  44.                 return true;  
  45.             }  
  46.             break;    
  47.         }  
  48.         // greater than  
  49.         case ">":  
  50.         case "gt":  
  51.         {  
  52.             if (abs($float1 - $float2) < $epsilon) {  
  53.                 return false;  
  54.             }  
  55.             else  
  56.             {  
  57.                 if ($float1 > $float2) {  
  58.                     return true;  
  59.                 }  
  60.             }  
  61.             break;    
  62.         }  
  63.         // greater than or equal  
  64.         case ">=":  
  65.         case "gte":  
  66.         {  
  67.             if (compareFloatNumbers($float1$float2'>') || compareFloatNumbers($float1$float2'=')) {  
  68.                 return true;  
  69.             }  
  70.             break;    
  71.         }  
  72.         case "<>":  
  73.         case "!=":  
  74.         case "ne":  
  75.         {  
  76.             if (abs($float1 - $float2) > $epsilon) {  
  77.                 return true;  
  78.             }  
  79.             break;    
  80.         }  
  81.         default:  
  82.         {  
  83.             die("Unknown operator '".$operator."' in compareFloatNumbers()");     
  84.         }  
  85.     }  
  86.       
  87.     return false;  
  88. }  
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.

0 comments:

Post a Comment