Your current ranges could potentially have gaps: 1.250001
would not be <= 1.25
, but would not be >= 1.26
either. You've tried to handle that with round()
, but the result of that is still a floating point number, and binary floating point does not accurately represent decimals. This isn't unique to PHP, it's something you'll encounter in basically every programming language (a very few have a separate type for fixed decimal numbers, trading performance for accuracy).
In particular, writing round(1.25, 2)
is never going to result in a different value from writing 1.25
, because the compiler will already have picked the closest floating point value to 1.25 possible.
The simple fix is to use the same boundary each time, but exclude equal values on second mention: rather than >= 1.26
in the second range, use > 1.25
. However, that makes it obvious that you have redundant tests anyway, because if something doesn't fall into the <= 1.25
bucket, you already know that it is > 1.25
, so don't need to test that again.
For readability (and an immeasurably tiny amount of performance), I would assign a local variable to round($comparedNumber, 2)
rather than pasting it into each check. You may also decide you don't want that rounding - its effect will be to put 1.251
into the ">0, <=1.25" bucket rather than the ">1.25, <=2.45" bucket.
So it simplifies down to this:
$comparedNumber = 1.2549999999;
$roundedNumber = round($comparedNumber, 2);
if ($roundedNumber <= 0) {
$selectedRange = 'Range not exist';
} elseif ($roundedNumber <= 1.25) {
$selectedRange = 'Range 1';
} elseif ($roundedNumber <= 2.45) {
$selectedRange = 'Range 2';
} elseif ($roundedNumber <= 5) {
$selectedRange = 'Range 3';
} else {
$selectedRange = 'Range 4';
}
Since you now only need one number to define each range, making this into a loop is simple:
foreach ( $ranges as $rangeName => $rangeBoundary ) {
if ( $roundedNumber <= $rangeBoundary ) {
$selectedRange = $rangeName;
break; // stops the loop carrying on with the next test
}
}