如何检查整数是不是在范围内?
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
和$max
。 filter_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 >= $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);
【讨论】:
这就是我所期望的 :) 不错!因为我需要它来告诉我是真是假,所以我添加了以下内容:function t1($val, $min, $max) if ($val >= $min && $val <= $max) return true; else return false;
@pathros 上面的函数已经返回true
或false
,无需额外编写代码
也不需要使用括号。 “返回 $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”是写起来不太方便。以上是关于如何检查整数是不是在范围内?的主要内容,如果未能解决你的问题,请参考以下文章