测试数字是奇数还是偶数。

305

在PHP中判断一个数字/变量是奇数还是偶数的最简单基本方法是什么?这与取模运算有关吗?

我尝试了一些脚本,但是谷歌现在没有给出答案。


11
"mod"是“模运算”的通用缩写术语,也被称为“模算术”。模算术 - Marc B
5
更多信息请参见此处,其中包括:要确定一个数是奇数还是偶数,使用位运算符*&*比取模运算更快更高效:$a=3; if($a&1){echo 'odd';}else{echo 'even';} //输出'odd' - ashleedawg
20个回答

628
你在考虑使用 mod 运算时是正确的。这里有一个表达式,如果 $number 是偶数就返回 true,否则返回 false:
$number % 2 == 0

适用于每个整数PHP值,同时可以参考算术运算符PHP

示例:

$number = 20;
if ($number % 2 == 0) {
  print "It's even";
}

输出:

它是偶数


14
如果您正在循环或大量使用此功能,建议考虑Arius2038建议的位检查方法,它非常快速。对于奇偶检查,位检查是我首选的方法。 - Martijn
代码运行正常,但我想知道背后的逻辑是什么?为什么“10 == 0”会返回true的值? - snlan
1
@Tim,如果5%2 = 1。逻辑是2 * 2 + 1 = 5。如何在PHP中获取2? - Hendry Tanaka
1
@Hendry - 你具体在问什么?是如何得到除法的商作为整数,还是其他问题? 如果是前者,你只需要对结果进行floor()操作;floor(5/2)=2。 - Joey Sabey
2
我可以建议使用三个等号===来获得更快的速度:$number % 2 === 0 - kasimir
显示剩余2条评论

221

另一个选项是简单的位检查。

n & 1
例如:
if ( $num & 1 ) {
  //odd
} else {
  //even
}

1
这绝对是在像C这样的语言中使用整数时最快的方法,而且速度要快得多。是否有人进行了基准测试来确定在PHP中是否也是如此? - thomasrutter
1
如果PHP引擎编写得很好,那么这可能是最快的方法。 - Rolf
1
我会说这是最快速和最直接的方式。完美。 - Robbiegod
5
以上链接已失效。这里有另一个很好的解释:http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/。 - kasimir

27

可以使用 mod 运算符。

$even = ($num % 2 == 0);
$odd = ($num % 2 != 0);

9

虽然所有的答案都很好且正确,但一个简单的一行解决方案是:

$check = 9;

要么:

echo ($check & 1 ? 'Odd' : 'Even');

或者:

echo ($check % 2 ? 'Odd' : 'Even');

非常好用。

那么,使用这个答案还是这个答案?干得好。 - miken32

8
(bool)($number & 1)

或者
(bool)(~ $number & 1)

3
这是一个位运算符,我认为除非你知道如何使用这种花哨的东西,否则最好避免使用这个语法。 - danhere
1
我必须钦佩这种语法,它能够在不知道原因的情况下正常工作,提醒我们在物理、数学和其他领域中是多么渺小。只需在数字1上添加一行,而不是2... - Jonas Lundman
我在JS中经常使用位运算符。例如,使用if (~string.indexOf("@")) {}代替if (string.indexOf("@") !== -1) {}。我喜欢看到条件结果简单地为true或false。但是,对于不熟悉这种语法的人来说,可能有点困惑。 - Martin James
1
@MartinJames:“我更喜欢看到条件结果是简单的true或false。”这正是像! == -1=== 0这样的技术所做的。以下是使用位运算符进行除位运算以外的任何操作的问题:您会让读者承担理解您意图的负担。至少,您应该在使用该技术的任何地方添加注释。或编写一个命名良好的函数并调用它。对我来说,这似乎是一种不必要的微观优化。如果我与您一起工作,我会要求您改为使用明显的运算符和表达式的标准用法。 - ToolmakerSteve

6
另一种选择是检查最后一位数字是否为偶数:
$value = "1024";// A Number
$even = array(0, 2, 4, 6, 8);
if(in_array(substr($value, -1),$even)){
  // Even Number
}else{
  // Odd Number
}

或者为了更快,使用isset()而不是array_search
$value = "1024";// A Number
$even = array(0 => 1, 2 => 1, 4 => 1, 6 => 1, 8 => 1);
if(isset($even[substr($value, -1)]){
  // Even Number
}else{
  // Odd Number
}

或者让它更快(有时比模运算符更快):(点击此处查看)
$even = array(0, 2, 4, 6, 8);
if(in_array(substr($number, -1),$even)){
  // Even Number
}else{
  // Odd Number
}

这是作为我的发现证明的时间测试

给下投票者:请问您为什么要给我点踩? - Subin
5
与其他方法相比,这非常昂贵。 - grantwparks
@grantwparks 嗯,使用 issetmod 的区别只有0.5007秒。但是,array_search 很昂贵。 - Subin
2
@grantwparks,我已经更新了代码,包括in_array,有时会比模运算更好。 - Subin
1
虽然思路有趣。它基本上是 $num & 1 的十进制版本 :). 你也可以用十六进制来做:array(0, 2, 4, 6, 8, A, C, E, F) :D。 - Matthijs Wessels
显示剩余3条评论

6

我进行了一些测试,发现在mod、is_int&运算符之间,mod是最快的,紧随其后的是&运算符。而is_int比mod慢近4倍。

I used the following code for testing purposes:

$number = 13;

$before = microtime(true);
for ($i=0; $i<100000; $i++) {
    $test = ($number%2?true:false);
}
$after = microtime(true);

echo $after-$before." seconds mod<br>";

$before = microtime(true);
for ($i=0; $i<100000; $i++) {
    $test = (!is_int($number/2)?true:false);
}
$after = microtime(true);

echo $after-$before." seconds is_int<br>";

$before = microtime(true);
for ($i=0; $i<100000; $i++) {
    $test = ($number&1?true:false);
}
$after = microtime(true);

echo $after-$before." seconds & operator<br>";

The results I got were pretty consistent. Here's a sample:

0.041879177093506 seconds mod
0.15969395637512 seconds is_int
0.044223070144653 seconds & operator


2
在我的服务器上(5.4.4 / cli / no opcache / i7),"&" 比 mod 快大约10%(在具有随机整数值的数组上进行了测试)。 - Pawel Dubiel
1
“is_int”方法让我感到不太妥当。它依赖于整数除法的确切实现细节。无论性能如何,我都会避免使用它。 - ToolmakerSteve

5

PHP会自动将null和空字符串转换为零。这也会在取模运算中发生。因此,代码如下:

$number % 2 == 0 or !($number & 1)

当$value =''或$value=null时,结果为true。我进行了更加详细的测试:

function testEven($pArg){
    if(is_int($pArg) === true){
        $p = ($pArg % 2);
        if($p === 0){
            print "The input '".$pArg."' is even.<br>";
        }else{
            print "The input '".$pArg."' is odd.<br>";
        }
    }else{
        print "The input '".$pArg."' is not a number.<br>";
    }
}

The print is there for testing purposes, hence in practice it becomes:
function testEven($pArg){
    if(is_int($pArg)=== true){
        return $pArg%2;
    }
    return false;
}

这个函数对于任何奇数返回1,对于任何偶数返回0,当它不是一个数字时返回false。我总是写 === true 或 === false 来让自己(和其他程序员)知道测试的意图。


1
注意:在PHP中,语言的“松散性”意味着经常遇到表示为字符串的整数(当然无法通过is_int测试)。例如,在与网站上的SQL交互时。相反,我将使用is_numeric,它将拒绝空值和空字符串。但是,这将允许浮点数和浮点数表示字符串,因此可能需要进行其他测试才能彻底。 - ToolmakerSteve
这个答案是为了基本回答而返回的问题。您绝对正确,在正常应用程序中需要额外的代码,但这超出了问题的范围。我在这个答案中的主要观点是应该使用运算符===而不是运算符==。当输入为0、""、null或false时,最后一个运算符将返回'even'。 - Loek Bergman
1
建议使用 is_int 是很好的。在生产代码中,我可能会将其扩展为 if (!is_numeric($pArg)) ..throw-some-exception..; $p = (int)$pArg; return ($p % 2) == 0; Bug: 你从最后一段代码片段中省略了 == 0return $pArg%2; 对于偶数返回 0(因此为“false”)。小问题: 你在不需要的地方使用了 ===is_int 只能返回 truefalse,因此可以安全地省略 === true - ToolmakerSteve
该函数回答了两个问题:它是一个整数吗?如果是,它是奇数还是偶数?因此需要三态值。凭借您的专业知识,您应该已经知道了。我使用Java编程,并且必须习惯于0不自动与false区分开来的事实。我对原始值使用true/false,对标量值使用null。并且总是使用===运算符。在Java中,null是一个对象,因此在测试原始值时不使用它。 - Loek Bergman
1
感谢您编辑答案以澄清函数返回的值。 - ToolmakerSteve
显示剩余2条评论

2

所有偶数除以2得到的结果都是整数

$number = 4;
if(is_int($number/2))
{
   echo("Integer");
}
else
{
   echo("Not Integer");
}

“is_int”方法让我感到不太妥当。它依赖于整数除法的确切实现细节。无论性能如何,我都会避免使用它。 - ToolmakerSteve

1
这段代码在PHP中检查数字是奇数还是偶数。在此示例中,$a的值为2,表示它是一个偶数。如果你需要奇数,请更改$a的值。
$a=2;
if($a %2 == 0){
    echo "<h3>This Number is <b>$a</b> Even</h3>";
}else{
    echo "<h3>This Number is <b>$a</b> Odd</h3>";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接