303

What is the simplest most basic way to find out if a number/variable is odd or even in PHP? Is it something to do with mod?

I've tried a few scripts but.. google isn't delivering at the moment.

user1022585
  • 13,061
  • 21
  • 55
  • 75
  • 11
    mod is the generic shorthand term for 'modulo', aka [modular arithmetic](http://en.wikipedia.org/wiki/Modular_arithmetic) – Marc B Oct 31 '11 at 20:20
  • 5
    More info [here](https://www.php.net/manual/internals2.opcodes.mod.php) including: *To determine odd or even it's faster and more efficient to use the **bitwise* `&` *operator**:* `$a=3; if($a&1){echo 'odd';}else{echo 'even';} //returns 'odd'` – ashleedawg Jul 28 '19 at 17:35

17 Answers17

624

You were right in thinking mod was a good place to start. Here is an expression which will return true if $number is even, false if odd:

$number % 2 == 0

Works for every integerPHP value, see as well Arithmetic OperatorsPHP.

Example:

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

Output:

It's even

Francisco Luz
  • 2,775
  • 2
  • 25
  • 35
  • 14
    If you use this in loops or large quantities, you might want to consider the bitcheck suggested by Arius2038, which is very fast. The bitcheck is my prefered method for odd/even checks. – Martijn Jul 03 '13 at 09:48
  • Works fine but I'm just wondering whats the logic behind this? Why is it that a value of true is given if "10 == 0" ? – snlan Sep 24 '14 at 11:42
  • The logic is that any even number is divisible by 2 with no remainder. If you used $number % 10, and your $number was 20, it would return true, but not if your $number was 22. You could use $number % 10 if you were trying to find every 10th item in a loop for example. – crdunst Sep 25 '14 at 15:33
  • 1
    @Tim, if 5%2=1. The logica is 2*2+1=5.How to get the 2 in php? – Hendry Tanaka Oct 23 '14 at 02:22
  • 1
    @Hendry - what are you asking exactly? How to get the quotient for a division as a whole number, or...? If that is what you mean, you just need to floor() the result; floor(5/2)=2 – Joey Sabey Mar 20 '15 at 14:25
  • 2
    Might I suggest a triple `=` for fractional speed improvement: `$number % 2 === 0` – kasimir Jun 11 '15 at 11:20
  • NOTE: to also handle float values, testing nearest integer, do `if ((int)round($number) % 2 === 0)`. If omit "round", this is truncation, which I don't recommend: a floating point number could display as if it were a whole value (e.g. `1.0`), yet be a hair below that whole value. If really need truncation, then add a small offset: `if ((int)($number + 0.00001) % 2 === 0)`. The amount of offset to add depends on your circumstances. – ToolmakerSteve Jul 27 '20 at 22:08
221

Another option is a simple bit checking.

n & 1

for example:

if ( $num & 1 ) {
  //odd
} else {
  //even
}
Pawel Dubiel
  • 18,665
  • 3
  • 40
  • 58
  • 1
    This would definitely be the fastest way when using integers in a language like C, by a large margin. Has anyone done benchmarks to determine if this is true also for PHP? – thomasrutter Dec 05 '13 at 00:03
  • 1
    It's probably the fastest way, if the PHP engine was well coded. – Rolf Dec 18 '13 at 16:19
  • 1
    I'd say this is the fastest and most straight forward way. Perfect. – Robbiegod Mar 27 '14 at 19:03
  • 5
    Above link is dead. Here's another good explanation: http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/ – kasimir Jun 11 '15 at 11:25
27

Yes using the mod

$even = ($num % 2 == 0);
$odd = ($num % 2 != 0);
Aaron W.
  • 9,254
  • 2
  • 34
  • 45
9

While all of the answers are good and correct, simple solution in one line is:

$check = 9;

either:

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

or:

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

works very well.

Tarik
  • 4,270
  • 38
  • 35
  • So, use [this answer](https://stackoverflow.com/a/9153969/1255289) or [this answer](https://stackoverflow.com/a/7959256/1255289)? Great work. – miken32 Sep 14 '22 at 12:43
8
(bool)($number & 1)

or

(bool)(~ $number & 1)
Olegs
  • 81
  • 1
  • 1
  • 3
    This is a bitwise operator I believe so unless you know what you're doing with that fancyness, I would avoid this syntax. – danhere Dec 12 '13 at 20:41
  • 1
    I have to admire the syntax, things that works without knowing why, gives you a reminder of how small we are in the world of fysics, math and, well, just add a row on number 1, not 2... – Jonas Lundman Dec 06 '17 at 11:58
  • I use bitwise operators in JS quite a bit. For example `if (~string.indexOf("@")) {}` instead of `if (string.indexOf("@") !== -1) {}`. I prefer to see conditions result in a simple true or false. But yes, it can be a little confusing to people that aren't familiar with this syntax. – Martin James Jan 27 '19 at 14:22
  • 1
    @MartinJames: re *"I prefer to see conditions result in a simple true or false."* which is exactly what techniques such as `!== -1` or `=== 0` do. Here's the problem with using bitwise operators to do anything other than a bitwise operation: you are placing a burden on the reader, to understand your intent. At minimum, you should *add a comment* anywhere you use that technique. Or write a well-named function and call it. Smells like an unnecessary micro-optimization to me. Seriously, if I was working with you, I would ask you to change to standard usage of obvious operators and expressions. – ToolmakerSteve Jul 27 '20 at 22:42
6

I did a bit of testing, and found that between mod, is_int and the &-operator, mod is the fastest, followed closely by the &-operator. is_int is nearly 4 times slower than mod.

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
Ruben Coolen
  • 376
  • 1
  • 5
  • 13
  • 2
    on my server ( 5.4.4 / cli / no opcache / i7 ) the "&" is about 10% faster then mod ( tested on array with random integer values ) – Pawel Dubiel Dec 05 '13 at 09:08
  • 1
    The `is_int` approach "smells" to me. It relies on the exact implementation details of integer division. I would avoid it, regardless of performance. – ToolmakerSteve Jul 27 '20 at 22:18
6

Another option is to check if the last digit is an even number :

$value = "1024";// A Number
$even = array(0, 2, 4, 6, 8);
if(in_array(substr($value, -1),$even)){
  // Even Number
}else{
  // Odd Number
}

Or to make it faster, use isset() instead of 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
}

Or to make it more faster (beats mod operator at times) :

$even = array(0, 2, 4, 6, 8);
if(in_array(substr($number, -1),$even)){
  // Even Number
}else{
  // Odd Number
}

Here is the time test as a proof to my findings.

Subin
  • 3,445
  • 1
  • 34
  • 63
  • To Downvoter : May I please know why you downvoted ? – Subin Mar 03 '14 at 13:58
  • 5
    It's very expensive, compared to other methods. – grantwparks Apr 22 '15 at 17:02
  • @grantwparks Well, the difference between using **isset** & **mod** is only 0.5007 seconds. But, **array_search** is very expensive. – Subin Apr 24 '15 at 05:37
  • Those aren't seconds in the test, they're actually much less. So on the surface, it sounds reasonable. But think of this: in the results, mod came out at 2.0xxxx units of time. While isset came out at 2.5xxxx units of time. That's a 25% increase in execution time. How reasonable does it sound now ;) – grantwparks May 01 '15 at 15:40
  • @grantwparks Well, you're right. This answer is only for information and I suggest using mod. – Subin May 03 '15 at 14:43
  • 2
    @grantwparks I have update the code to include `in_array` which beats mod operator sometimes. – Subin Mar 16 '16 at 03:26
  • 1
    Interesting way of thinking though. It's basically the decimal version of `$num & 1` :). You could also do it hexadecimal: array(0, 2, 4, 6, 8, A, C, E, F) :D. – Matthijs Wessels Feb 01 '17 at 14:30
  • Please don't do this, IMHO. Relying on the decimal string representation of an integer is not a good way to think about numeric operations. If anyone on my team used this technique, I would be quite concerned about their grasp of mathematics; suggest they speak with another programmer next time they encountered a math problem. If you want a more specific complaint, this technique doesn't generalize to other divisors: Suppose we next need to know whether a value is divisible by 3. You've gone down a dead-end road. – ToolmakerSteve Jul 27 '20 at 22:14
5

PHP is converting null and an empty string automatically to a zero. That happens with modulo as well. Therefor will the code

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

with value $number = '' or $number = null result in true. I test it therefor somewhat more extended:

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;
}

This function returns 1 for any odd number, 0 for any even number and false when it is not a number. I always write === true or === false to let myself (and other programmers) know that the test is as intended.

Loek Bergman
  • 2,192
  • 20
  • 18
  • 1
    CAUTION: In php, the "looseness" of the language means one often encounters an integer represented as a string (which of course fails `is_int` test). For example, when interacting with SQL on a website. I would instead use `is_numeric`, which will reject null and empty string. However, that will allow floats and float-representation-strings, so may need additional tests to be thorough. – ToolmakerSteve Jul 27 '20 at 22:22
  • This answer is returned with the question for a basic answer in mind. You are absolutely right that in a normal application extra code is required, but that is out of scope of the question. My main point in this answer is that the operator === should be used instead of the operator ==. The last operator will return 'even' when the input is 0, "", null or false. – Loek Bergman Jul 30 '20 at 23:28
  • 1
    OK. **Suggesting `is_int` is good.** In production code I might expand this to `if (!is_numeric($pArg)) ..throw-some-exception..; $p = (int)$pArg; return ($p % 2) == 0;` **Bug:** you omitted `== 0` from last snippet: `return $pArg%2;` returns `0` (so "false") for even numbers. **Minor nit:** You use `===` in a place where it is not at all needed. `is_int` can *only* return `true` or `false`, so `=== true` can be safely omitted there. – ToolmakerSteve Aug 29 '20 at 20:23
  • Suggestion: Exception throwing is very important in constructing robust code, I agree. Yet in some functions I wonder if it is wise to throw an exception and return a false instead. Throwing an exception implies that the process ends. Are mistakes in all functions really that important? Bug: Could be a bug if I test with ==, yet I always test with ===. Then is 0 different from false. Minor nit: Correct that it can be omitted. I write it in PHP though, to show the other programmers that this is the check to be executed. It is for maintenance purposes only. – Loek Bergman Sep 03 '20 at 07:51
  • The code returns a value. In this case 0, 1 or false. The caller of this function has to test using the === in order to make this distinction. It would be more robust code indeed when the function returns 2,3 or false like this 'return ($pArg % 2) === 0 ? 2 : 3;'. Even if the caller uses == then will these values never create any confusion. – Loek Bergman Sep 05 '20 at 14:16
  • The function answers two questions: is it an int? If so, is it odd or even? Hence is a tri-state value required. With your expert knowledge you should have known. I programmed in Java and had to get used to the fact that 0 is not automatically different from false. I use true/false for primitive values and null for scalar ones. And always the === - operator. In Java null is an object, so I don't use it when testing primitive values. – Loek Bergman Sep 08 '20 at 14:24
  • 1
    Thank you for editing the answer to clarify the values returned by your function. – ToolmakerSteve Sep 08 '20 at 19:52
2

All even numbers divided by 2 will result in an integer

$number = 4;
if(is_int($number/2))
{
   echo("Integer");
}
else
{
   echo("Not Integer");
}
David S.
  • 55
  • 1
  • The `is_int` approach "smells" to me. It relies on the exact implementation details of integer division. I would avoid it, regardless of performance. – ToolmakerSteve Jul 27 '20 at 22:18
0

I am making an assumption that there is a counter already in place. in $i which is incremented at the end of a loop, This works for me using a shorthand query.

$row_pos = ($i & 1) ? 'odd' : 'even';

So what does this do, well it queries the statement we are making in essence $i is odd, depending whether its true or false will decide what gets returned. The returned value populates our variable $row_pos

My use of this is to place it inside the foreach loop, right before i need it, This makes it a very efficient one liner to give me the appropriate class names, this is because i already have a counter for the id's to make use of later in the program. This is a brief example of how i will use this part.

<div class='row-{$row_pos}'> random data <div>

This gives me odd and even classes on each row so i can use the correct class and stripe my printed results down the page.

The full example of what i use note the id has the counter applied to it and the class has my odd/even result applied to it.:

$i=0;
foreach ($a as $k => $v) {

    $row_pos = ($i & 1) ? 'odd' : 'even';
    echo "<div id='A{$i}' class='row-{$row_pos}'>{$v['f_name']} {$v['l_name']} - {$v['amount']} - {$v['date']}</div>\n";

$i++;
}

in summary, this gives me a very simple way to create a pretty table.

CodingInTheUK
  • 930
  • 7
  • 16
0

Try this,

$number = 10;
 switch ($number%2)
 {
 case 0:
 echo "It's even";
 break;
 default:
 echo "It's odd";
 }
Sajjad Hossain
  • 185
  • 3
  • 14
-1
$before = microtime(true);

$n = 1000;  
$numbers = range(1,$n);

$cube_numbers = array_map('cube',$numbers);

function cube($n){      
    $msg ='even';       
    if($n%2 !=0){
        $msg = 'odd';
    }               
    return "The Number is $n is ".$msg;
}

foreach($cube_numbers as $cube){
    echo $cube . "<br/>";
}

$after = microtime(true);

echo $after-$before. 'seconds';
user2610558
  • 75
  • 2
  • 2
-1

$number %2 = 1 if odd... so don't have to use not even...

$number = 27;

if ($number % 2 == 1) {
  print "It's odd";
}
jxwd
  • 179
  • 2
  • 6
-1
<?php
// Recursive function to check whether
// the number is Even or Odd 
function check($number){
    if($number == 0)
        return 1;
    else if($number == 1)
        return 0;
    else if($number<0)
        return check(-$number);
    else
        return check($number-2);        
}
  
// Check the number odd or even
$number = 35;
if(check($number))
    echo "Even";
else
    echo "Odd";
?>

So, the output will be Odd

Balaji
  • 37
  • 1
  • 7
  • 4
    That's a ludicrously inefficient approach to solving the problem, so much so that it will fall over on large numbers as it will run out of memory. – Quentin Aug 25 '21 at 15:41
-2
//checking even and odd
$num =14;

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

if($even){
    echo "Number is even.";
} else {
    echo "Number is odd.";
}
Imran Azim
  • 154
  • 1
  • 8
-2

Try this one with #Input field

<?php
    //checking even and odd
    echo '<form action="" method="post">';
    echo "<input type='text' name='num'>\n";
    echo "<button type='submit' name='submit'>Check</button>\n";
    echo "</form>";

    $num = 0;
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
      if (empty($_POST["num"])) {
        $numErr = "<span style ='color: red;'>Number is required.</span>";
        echo $numErr;
        die();
      } else {
          $num = $_POST["num"];
      }


    $even = ($num % 2 == 0);
    $odd = ($num % 2 != 0);
    if ($num > 0){
        if($even){
            echo "Number is even.";
        } else {
            echo "Number is odd.";
        }
    } else {
        echo "Not a number.";
    }
    }
?>
Imran Azim
  • 154
  • 1
  • 8
-2

Two simple bitwise functions, returning a 0 for False and 1 for True.

# is_odd: 1 for odd , 0 for even
odd = number & 1

# is_even: 1 for even , 0 for odd
even = number & 1 ^ 1
Syscall
  • 19,327
  • 10
  • 37
  • 52
cinsight
  • 1
  • 1