90

How can I check if a given number is within a range of numbers?

kenorb
  • 137,499
  • 74
  • 643
  • 694
Richard Peers
  • 1,011
  • 2
  • 9
  • 7
  • 1
    Related: [How to check if integer is between a range?](http://stackoverflow.com/q/5029409/55075) – kenorb Mar 12 '15 at 18:41

15 Answers15

158

The expression:

 ($min <= $value) && ($value <= $max)

will be true if $value is between $min and $max, inclusively

See the PHP docs for more on comparison operators

kba
  • 19,080
  • 5
  • 59
  • 87
Dancrumb
  • 25,148
  • 10
  • 67
  • 128
  • No it won't. Both comparison operators should be <=, or the operands of the second part of the expression should be swapped. ($value should not be greater than $max). – GolezTrol Jan 13 '11 at 19:00
  • You must have added that comment while I was correcting my error... this expression is now correct – Dancrumb Jan 13 '11 at 19:02
  • 3
    Depending on whether the OP really means "integer" when asking for "integer" this will produce false results when `$value` is a float. Also, since the comparison is loose, passing a string might produce false result, e.g. `(0 <= 'string') && ('string' <= 10) );` is `true` due to type juggling. – Gordon Jan 13 '11 at 19:14
  • @Gordon, only if you wish the boundary values to be treated inclusively... but a valid point, nonetheless – Dancrumb Jan 14 '11 at 16:37
  • While it's true that the PHP interpreter does not require the parentheses, it's a matter of style as to whether it is helpful to engineers. Personally, I like the explicit nature of the parentheses in this expression and I don't think they add clutter. However, I think that they would start to feel noisy if you include the `(int)` casts. In that instance, I would probably elect to leave them out. – Dancrumb Oct 11 '16 at 14:40
  • there is no provided helper function in PHP to check if a number between 2 numbers? – Ebrahim Bashirpour Feb 14 '21 at 09:04
127

You can use filter_var

filter_var(
    $yourInteger, 
    FILTER_VALIDATE_INT, 
    array(
        'options' => array(
            'min_range' => $min, 
            'max_range' => $max
        )
    )
);

This will also allow you to specify whether you want to allow octal and hex notation of integers. Note that the function is type-safe. 5.5 is not an integer but a float and will not validate.

Detailed tutorial about filtering data with PHP:

jagb
  • 834
  • 10
  • 26
Gordon
  • 305,248
  • 71
  • 524
  • 547
45

Might help:

if ( in_array(2, range(1,7)) ) {
    echo 'Number 2 is in range 1-7';
}

http://php.net/manual/en/function.range.php

Bobz
  • 2,207
  • 1
  • 17
  • 22
  • 20
    Worth noting that has a memory cost due to the generation of the range. – Dancrumb Dec 01 '17 at 16:24
  • 3
    @pr1nc3 but this solution is very slow and very memory hungry when it's a large range. – hanshenrik Jan 02 '19 at 18:06
  • Agreed, this is way less elegant than the accepted solution and it will take much longer to execute on larger arrays because you have to perform a search on the array to find the value. It's faster, less memory hungry, and just as few lines to use the accepted solution. – dmcoding Aug 17 '21 at 18:02
  • Does not handle float values – Richard Muvirimi Feb 21 '22 at 12:39
17

You could whip up a little helper function to do this:

/**
 * Determines if $number is between $min and $max
 *
 * @param  integer  $number     The number to test
 * @param  integer  $min        The minimum value in the range
 * @param  integer  $max        The maximum value in the range
 * @param  boolean  $inclusive  Whether the range should be inclusive or not
 * @return boolean              Whether the number was in the range
 */
function in_range($number, $min, $max, $inclusive = FALSE)
{
    if (is_int($number) && is_int($min) && is_int($max))
    {
        return $inclusive
            ? ($number >= $min && $number <= $max)
            : ($number > $min && $number < $max) ;
    }

    return FALSE;
}

And you would use it like so:

var_dump(in_range(5, 0, 10));        // TRUE
var_dump(in_range(1, 0, 1));         // FALSE
var_dump(in_range(1, 0, 1, TRUE));   // TRUE
var_dump(in_range(11, 0, 10, TRUE)); // FALSE

// etc...
Vincent Savard
  • 32,695
  • 10
  • 65
  • 72
Luke
  • 3,844
  • 19
  • 35
9
if (($num >= $lower_boundary) && ($num <= $upper_boundary)) {

You may want to adjust the comparison operators if you want the boundary values not to be valid.

lonesomeday
  • 224,675
  • 49
  • 309
  • 312
6

You can try the following one-statement:

if (($x-$min)*($x-$max) < 0)

or:

if (max(min($x, $max), $min) == $x)
kenorb
  • 137,499
  • 74
  • 643
  • 694
5

Some other possibilities:

if (in_array($value, range($min, $max), true)) {
    echo "You can be sure that $min <= $value <= $max";
}

Or:

if ($value === min(max($value, $min), $max)) {
    echo "You can be sure that $min <= $value <= $max";
}

Actually this is what is use to cast a value which is out of the range to the closest end of it.

$value = min(max($value, $min), $max);

Example

/**
 * This is un-sanitized user input.
 */
$posts_per_page = 999;

/**
 * Sanitize $posts_per_page.
 */
$posts_per_page = min(max($posts_per_page, 5), 30);

/**
 * Use.
 */
var_dump($posts_per_page); // Output: int(30)
Nabil Kadimi
  • 9,428
  • 2
  • 49
  • 56
1

using a switch case

    switch ($num){

        case ($num>= $value1 && $num<= $value2): 
            echo "within range 1";
        break;
        case ($num>= $value3 && $num<= $value4): 
            echo "within range 2";
        break;
        .
        .
        .
        .
        .

        default: //default
            echo "within no range";
        break;
     }
Jefkine Kafunah
  • 130
  • 1
  • 5
  • 4
    Should be `switch(true)`, otherwise if `$num == 0`, the case logic fails because PHP tries to match `0 == ($num>= $value1 && $num<= $value2)`, etc. I've suggested this as an edit. – Zane Nov 30 '15 at 05:28
0

Another way to do this with simple if/else range. For ex:

$watermarkSize = 0;

if (($originalImageWidth >= 0) && ($originalImageWidth <= 640)) {
    $watermarkSize = 10;
} else if (($originalImageWidth >= 641) && ($originalImageWidth <= 1024)) {
    $watermarkSize = 25;
} else if (($originalImageWidth >= 1025) && ($originalImageWidth <= 2048)) {
    $watermarkSize = 50;
} else if (($originalImageWidth >= 2049) && ($originalImageWidth <= 4096)) {
    $watermarkSize = 100;
} else {
    $watermarkSize = 200;
}
Gajen Sunthara
  • 3,902
  • 31
  • 22
0

I created a function to check if times in an array overlap somehow:

    /**
     * Function to check if there are overlapping times in an array of \DateTime objects.
     *
     * @param $ranges
     *
     * @return \DateTime[]|bool
     */
    public function timesOverlap($ranges) {
        foreach ($ranges as $k1 => $t1) {
            foreach ($ranges as $k2 => $t2) {
                if ($k1 != $k2) {
                    /* @var \DateTime[] $t1 */
                    /* @var \DateTime[] $t2 */
                    $a = $t1[0]->getTimestamp();
                    $b = $t1[1]->getTimestamp();
                    $c = $t2[0]->getTimestamp();
                    $d = $t2[1]->getTimestamp();

                    if (($c >= $a && $c <= $b) || $d >= $a && $d <= $b) {
                        return true;
                    }
                }
            }
        }

        return false;
    }
Link
  • 29
  • 5
0

Here is my little contribution:

function inRange($number) {
  $ranges = [0, 13, 17, 24, 34, 44, 54, 65, 200];
  $n = count($ranges);

  while($n--){
    if( $number > $ranges[$n] )
      return $ranges[$n]+1 .'-'. $ranges[$n + 1];
  }
Miquel
  • 59
  • 1
  • 2
0

I have function for my case

Use:

echo checkRangeNumber(0);
echo checkRangeNumber(1);
echo checkRangeNumber(499);
echo checkRangeNumber(500);
echo checkRangeNumber(501);
echo checkRangeNumber(3001);
echo checkRangeNumber(999);

//return

0
1-500
1-500
1-500
501-1000
3000-3500
501-1000

function checkRangeNumber($number, $per_page = 500)
{
    //$per_page = 500; // it's fixed number, but... 

    if ($number == 0) {
        return "0";
    }

    $num_page = ceil($number / $per_page); // returns 65
    $low_limit = ($num_page - 1) * $per_page + 1; // returns 32000
    $up_limit = $num_page * $per_page; // returns 40
    return  "$low_limit-$up_limit";
}
Hoàng Vũ Tgtt
  • 1,597
  • 20
  • 7
-1
function limit_range($num, $min, $max)
{
  // Now limit it
  return $num>$max?$max:$num<$min?$min:$num;
}

$min = 0;  // Minimum number can be
$max = 4;  // Maximum number can be
$num = 10;  // Your number
// Number returned is limited to be minimum 0 and maximum 4
echo limit_range($num, $min, $max); // return 4
$num = 2;
echo limit_range($num, $min, $max); // return 2
$num = -1;
echo limit_range($num, $min, $max); // return 0
Justin Levene
  • 1,538
  • 18
  • 15
-1
$ranges = [
    1 => [
        'min_range' => 0.01,
        'max_range' => 199.99
    ],
    2 => [
        'min_range' => 200.00,
    ],
];

foreach($ranges as $value => $range){
    if(filter_var($cartTotal, FILTER_VALIDATE_FLOAT, ['options' => $range])){
        return $value;
    }
}
-1

Thank you so much and I got my answer by adding a break in the foreach loop and now it is working fine.

Here are the updated answer:

foreach ($this->crud->getDataAll('shipping_charges') as $ship) {
  if ($weight >= $ship->low && $weight <= $ship->high) {
      $val = $ship->amount;
      break;
      }
      else
      {
        $val = 900;
      }
     }
     echo $val ;
Code GuruDev
  • 197
  • 1
  • 10