Как проверить, находится ли целое число в диапазоне? - PullRequest
66 голосов
/ 17 февраля 2011

Есть ли способ проверить диапазон без выполнения этого избыточного кода:

if ($int>$min && $int<$max)

Как функция:

function testRange($int,$min,$max){
    return ($min<$int && $int<$max);
}

использование:

if (testRange($int,$min,$max)) 

Есть ли в PHP такая встроенная функция? Или любой другой способ сделать это?

Ответы [ 8 ]

84 голосов
/ 21 июля 2013

Проверено 3 способа с циклом 1000000 раз.

t1_test1: ($val >= $min && $val <= $max): 0,3823 мс

t2_test2: (in_array($val, range($min, $max)): 9,3301 мс

t3_test3: (max(min($var, $max), $min) == $val): 0,7272 мс

T1 был самым быстрым, в основном это было:

function t1($val, $min, $max) {
  return ($val >= $min && $val <= $max);
}
47 голосов
/ 17 февраля 2011

Не думаю, что вы получите лучший способ, чем ваша функция.

Это чисто, легко следовать и понимать, и возвращает результат условия (без return (...) ? true : false беспорядок).

16 голосов
/ 18 февраля 2013

Встроенной функции нет, но вы можете легко достичь ее, вызвав соответствующие функции min() и max().

// Limit integer between 1 and 100000
$var = max(min($var, 100000), 1);
10 голосов
/ 27 января 2014

В большинстве приведенных примеров предполагается, что для тестового диапазона [$ a .. $ b], $ a <= $ b, т. Е. Экстремумы диапазона находятся в нижнем - верхнем порядке, и большинство предполагает, что все являются целыми числами. <br> Но мне нужна была функция для проверки, находится ли $ n между $ a и $ b, как описано здесь:

Check if $n is between $a and $b even if:
    $a < $b  
    $a > $b
    $a = $b

All numbers can be real, not only integer.

Существует простой способ проверки.
Я основываю тест на том факте, что ($n-$a) и ($n-$b) имеют разные знаки, когда $ n находится между $ a и $ b, и тот же знак, когда $ n находится вне диапазона $ a .. $ b.
Эта функция действительна для проверки увеличения, уменьшения, положительных и отрицательных чисел, не ограничивается проверкой только целых чисел.

function between($n, $a, $b)
{
    return (($a==$n)&&($b==$n))? true : ($n-$a)*($n-$b)<0;
}
6 голосов
/ 27 июня 2016

Я не могу комментировать (недостаточно репутации), поэтому я исправлю ответ Луиса Розти здесь:

function between($n, $a, $b) {
    return ($n-$a)*($n-$b) <= 0;
}

Эта функция работает также в случаях, когда n == a или n == b.

Доказательство: Пусть n принадлежит диапазону [a, b], где [a, b] является подмножеством действительных чисел.

Теперь a <= n <= b. Тогда n-a> = 0 и n-b <= 0. Это означает, что (n-a) * (n-b) <= 0. </p>

Случай b <= n <= a работает аналогично. </p>

3 голосов
/ 04 мая 2016

Также есть filter_var() и это встроенная функция, которая проверяет диапазон .Это не дает именно то, что вы хотите (никогда не возвращает истину), но с помощью "чит" мы можем изменить это.

Я не думаю, что это хороший код для удобства чтения, но я показываю, что это возможно:

return (filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]]) !== false)

Просто заполните $someNumber, $min и $max.filter_var с этим фильтром возвращает либо логическое значение false, когда число находится за пределами диапазона, либо само число, когда оно находится в пределах диапазона.Выражение (!== false) заставляет функцию возвращать значение true, когда число находится в пределах диапазона.

Если вы хотите как-то сократить его, помните о приведении типа.Если бы вы использовали !=, это было бы ложно для числа 0 в диапазоне -5;+5 (пока это должно быть правдой).То же самое произошло бы, если бы вы использовали приведение типа ((bool)).

// EXAMPLE OF WRONG USE, GIVES WRONG RESULTS WITH "0"
(bool)filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]])
if (filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]])) ...

Представьте себе (из другого ответа):

if(in_array($userScore, range(-5, 5))) echo 'your score is correct'; else echo 'incorrect, enter again';

Если пользователь напишет пустое значение ($userScore = '') это было бы правильно, так как in_array установлено здесь по умолчанию, не является более строгим, и это означает, что диапазон также создает 0 и '' == 0 (не строго), но '' !== 0 (есливы бы использовали строгий режим).Такие вещи легко пропустить, и поэтому я немного об этом написал. Мне стало известно, что строгие операторы используются по умолчанию, и программист может использовать нестрогие только в особых случаях .Я думаю, что это хороший урок.Большинство примеров приводят к неудаче в некоторых случаях, потому что не строгая проверка.

Тем не менее, мне нравится filter_var, и вы можете использовать функции выше (или ниже, если бы я так "поднялся";)) и сделать свой собственный обратный вызовкоторый вы будете использовать в качестве FILTER_CALLBACK фильтра.Вы можете вернуть bool или даже добавить параметр openRange.И еще один хороший момент: вы можете использовать другие функции , например, проверять диапазон каждого числа массивов или значений POST / GET.Это действительно мощный инструмент.

2 голосов
/ 17 февраля 2011

Использование операторов сравнения гораздо быстрее, чем вызов любой функции.Я не уверен на 100%, существует ли это, но думаю, что нет.

0 голосов
/ 29 ноября 2016

Вы можете сделать это, используя in_array() в сочетании с range()

if (in_array($value, range($min, $max))) {
    // Value is in range
}

Примечание Как отмечалось в комментариях, это не совсем хорошее решение, еслиВы сосредоточены на производительности.Генерация массива (особенно с большими диапазонами) замедлит выполнение.

...