如何检查整数是不是在范围内?

Posted

技术标签:

【中文标题】如何检查整数是不是在范围内?【英文标题】:How to check if an integer is within a range?如何检查整数是否在范围内? 【发布时间】:2011-06-29 02:26:34 【问题描述】:

有没有办法在不执行这些冗余代码的情况下测试范围:

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

?

像一个函数:

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

用法:

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

?

php有这样的内置函数吗?或者有其他方法吗?

【问题讨论】:

使用in_array()range() 有一种可怕的方式。除此之外,我不认为有一个 你为什么称它为“冗余代码”?这是必须评估的,不是吗? 确实如此。原始快速、可读的代码中哪一点是多余的,究竟是什么?谁会知道只是读取对您的 testRange() 的调用 testRange(1, 1, 2) 是对还是错? 我认为他指的是必须在条件中指定相同的变量两次。虽然我同意让你说if($int between $min and $max) 的语言结构会很好,但恐怕我见过的唯一语言是 SQL。 @Yes 就我个人而言,我认为使用函数会引入更多出错的可能性——例如,有可能以错误的顺序获取参数。另外,您是否想添加另一个函数来比较 ($int >= $min && $int 【参考方案1】:

一种可能性(不是解决方案):

$mysqli->query("SELECT $value BETWEEN $min and $max as test")->fetch_object()->test;

【讨论】:

【参考方案2】:

您可以使用in_array() 结合range() 来做到这一点

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

注意 然而,正如 cmets 中所指出的,如果您专注于性能,这并不是一个很好的解决方案。生成数组(尤其是范围较大的数组)会减慢执行速度。

【讨论】:

@Yukulélé 问题是:如何检查一个 INTEGER 是否在一个范围内? 查看我对 Nebuloasar 的回答。 这个想法有趣且可读,但是使用这种方式性能很差。 我认为这是一个不错的选择,感谢您的理解。所以,我删除了我的反对票。【参考方案3】:

我无法发表评论(没有足够的声誉),所以我会在这里修改 Luis Rosety 的回答:

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

此函数也适用于 n == a 或 n == b 的情况。

证明: 令 n 属于范围 [a,b],其中 [a,b] 是实数的子集。

现在 a = 0 和 n-b

案例 b

【讨论】:

间隔类型(打开或关闭)很重要。开放区间不包括限制,而封闭区间则包含限制。请参考en.wikipedia.org/wiki/Interval_(mathematics) 当然,在使用浮点数时,但在使用整数时(根据问题),这是无关紧要的。请记住,(a,b) 实际上是 [a+1, b-1] 与所有整数 a 和 b。 对我来说最好的答案【参考方案4】:

还有filter_var(),它是检查范围的本机函数。它不能准确地给出你想要的东西(从不返回 true),但是通过“作弊”我们可以改变它。

就可读性而言,我认为这不是一个好的代码,但我认为这是一种可能性:

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

只需填写$someNumber$min$maxfilter_var 使用该过滤器在数字超出范围时返回布尔值 false,或者在范围内时返回数字本身。当数字在范围内时,表达式 (!== false) 使函数返回 true。

如果您想以某种方式缩短它,请记住类型转换。如果您使用!=,那么在-5 范围内的数字0 将是错误的; +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 参数。还有其他好处:您可以使用other functions,例如检查每个数组或 POST/GET 值的范围。这是一个非常强大的工具。

【讨论】:

【参考方案5】:

大多数给定示例假设对于测试范围 [$a..$b],$a 但是我需要一个函数来测试 $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;

【讨论】:

这很好。请注意,如果 $n、$a 和 $b 碰巧是同一个数字,则此函数将返回 false,而大多数其他函数将返回 true。 感谢@bksunday 的评论。我已经在代码中添加了对这种情况的处理。 我必须为@bksunday 评论和我的答案添加精确度。区间可以是开区间或闭区间。开放间隔不包括限制,而封闭间隔确实包括限制。因此,对于来自 dynamic 的原始问题,它是一个开区间,因此当 $a=$b=$n 它应该返回 false ,因为它是我的原始函数,或者更简单:一个开区间($ a, $b) 与 $a=$b 是一个空集。 如果 $n=0,并且 $a=0 和 $b=1,这个 functionjs 返回 FALSE。为什么? 0 在范围内(介于 0 和 1 之间),所以应该返回 TRUE【参考方案6】:

用 1000000 次循环测试了你的 3 种方法。

t1_test1:($val &gt;= $min &amp;&amp; $val &lt;= $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);

【讨论】:

这就是我所期望的 :) 不错!因为我需要它来告诉我是真是假,所以我添加了以下内容:function t1($val, $min, $max) if ($val &gt;= $min &amp;&amp; $val &lt;= $max) return true; else return false; @pathros 上面的函数已经返回truefalse,无需额外编写代码 也不需要使用括号。 “返回 $val >= $min && $val 我不认为这个问题是关于性能的。其他语言对此有本地运算符,我认为这就是 OP 所寻找的。​​span> 【参考方案7】:

没有内置函数,但你可以通过适当地调用函数min()max()来轻松实现。

// Limit integer between 1 and 100000
$var = max(min($var, 100000), 1);

【讨论】:

这很有趣。但是,我不会纯粹为了可读性而使用它。 上面说的这个想法真的很有趣,但是它很难阅读,它调用了两个可以避免的函数。【参考方案8】:

我不认为你会得到比你的函数更好的方法。

它干净,易于理解和返回条件的结果(没有return (...) ? true : false混乱)。

【讨论】:

你说的这个“退货烂摊子”是什么?你能详细说明吗?提供一个坏与好做法的例子?谢谢!【参考方案9】:

使用比较运算符比调用任何函数都快得多。我不能 100% 确定这是否存在,但我认为它不存在。

【讨论】:

确实使用比较运算符比调用函数更快,因为 PHP 中的函数很慢。另一方面,它只是一个独立的函数,避免了每次重复操作符。中间方法可能是其他一些语言(如 C、C++ 或 Rust)中的宏。但是 PHP 没有此功能,也没有内置函数“between”,因此要使用函数,必须创建函数,或者使用答案中所说的“filter_var”,即使在这种情况下,“filter_var”是写起来不太方便。

以上是关于如何检查整数是不是在范围内?的主要内容,如果未能解决你的问题,请参考以下文章

检查输入到文本字段的值是不是是给定范围内的整数

检查 IP 地址是不是在范围/子网内的标准/安全方法

C如何检查内存地址是不是仍在范围内[关闭]

如何检查地理位置是不是在半径范围内?

如何检查位置是不是在给定范围内?

ORACLE SQL - 如何检查时间是不是在特定范围内?