How to compare if a floating point number against a set of floating point ranges?

Issue

Example, I have 4 ranges:

1. 0 – 1.25
2. 1.26 – 2.45
3. 2.46 – 5
4. 5.01 – infinity

And I have a floating point number to compare with: 1.2549999999.

I need to check to what range this number belongs.

I have the following code, but I’m not convinced it’s efficient enough

``````
\$comparedNumber = 1.2549999999;

if (0 < \$comparedNumber && round(\$comparedNumber, 2) <= round(1.25,2)) {
\$selectedRange = 'Range 1';
} elseif (  round(1.26,2) <= round(\$comparedNumber, 2)  && round(\$comparedNumber, 2) <= round(2.45,2)) {
\$selectedRange = 'Range 2';
} elseif (  round(2.46,2) <= round(\$comparedNumber, 2)  && round(\$comparedNumber, 2) <= round(5,2)) {
\$selectedRange = 'Range 3';
} elseif ( round(5.01,2) <= round(\$comparedNumber, 2) ) {
\$selectedRange = 'Range 4';
} else {
\$selectedRange = 'Range not exist';
}

print_r(\$selectedRange);
``````

Sample here

Solution

Your problem is poorly thought out boundaries, and trying to use equality to compare floating points. Rounding is not a solution: the return value of `round()` is still a floating point number.

For your "ranges" you have actually three boundaries: 1.26, 2.46, and 5.01.

A generalized solution would be:

``````<?php

\$numbers    = [1.2549999999, 1.28012, 2.01212, 4.012, 5.0000012, 5.012121001, -0.12];
\$boundaries = [1.26, 2.46, 5.01];

function checkRange(float \$number, array \$boundaries): int {

if (\$number < 0) {
return -1;
}

foreach (\$boundaries as \$i => \$boundary) {
if (\$number < \$boundary) {
return \$i + 1;
break;
}
}
return 4;
}

foreach (\$numbers as \$number) {
echo "\$number at Range ", checkRange(\$number, \$boundaries), "\n";
}

/*
Output:
1.2549999999 at Range 1
1.28012 at Range 2
2.01212 at Range 2
4.012 at Range 3
5.0000012 at Range 3
5.012121001 at Range 4
-0.12 at Range -1
*/
``````

As seen working here.

Note that the solution in the other answer fails to account for numbers in the range 4.

For this exercise, I treat numbers below 0 as "out of range", and put them in "range -1". What to do exactly with those is up to you.

This works for any given set of boundaries (as long as they are ordered), and does not need rounding at any point, since it’s moot for the comparison. A number is less than the boundary, or it’s not.

Answered By – yivi

Answer Checked By – Dawn Plyler (AngularFixing Volunteer)