How do I check if an integer is even or odd?

Viewed 461600

How can I check if a given number is even or odd in C?

31 Answers

Use the modulo (%) operator to check if there's a remainder when dividing by 2:

if (x % 2) { /* x is odd */ }

A few people have criticized my answer above stating that using x & 1 is "faster" or "more efficient". I do not believe this to be the case.

Out of curiosity, I created two trivial test case programs:

/* modulo.c */
#include <stdio.h>

int main(void)
{
    int x;
    for (x = 0; x < 10; x++)
        if (x % 2)
            printf("%d is odd\n", x);
    return 0;
}

/* and.c */
#include <stdio.h>

int main(void)
{
    int x;
    for (x = 0; x < 10; x++)
        if (x & 1)
            printf("%d is odd\n", x);
    return 0;
}

I then compiled these with gcc 4.1.3 on one of my machines 5 different times:

  • With no optimization flags.
  • With -O
  • With -Os
  • With -O2
  • With -O3

I examined the assembly output of each compile (using gcc -S) and found that in each case, the output for and.c and modulo.c were identical (they both used the andl $1, %eax instruction). I doubt this is a "new" feature, and I suspect it dates back to ancient versions. I also doubt any modern (made in the past 20 years) non-arcane compiler, commercial or open source, lacks such optimization. I would test on other compilers, but I don't have any available at the moment.

If anyone else would care to test other compilers and/or platform targets, and gets a different result, I'd be very interested to know.

Finally, the modulo version is guaranteed by the standard to work whether the integer is positive, negative or zero, regardless of the implementation's representation of signed integers. The bitwise-and version is not. Yes, I realise two's complement is somewhat ubiquitous, so this is not really an issue.

You guys are waaaaaaaay too efficient. What you really want is:

public boolean isOdd(int num) {
  int i = 0;
  boolean odd = false;

  while (i != num) {
    odd = !odd;
    i = i + 1;
  }

  return odd;
}

Repeat for isEven.

Of course, that doesn't work for negative numbers. But with brilliance comes sacrifice...

Use bit arithmetic:

if((x & 1) == 0)
    printf("EVEN!\n");
else
    printf("ODD!\n");

This is faster than using division or modulus.

[Joke mode="on"]

public enum Evenness
{
  Unknown = 0,
  Even = 1,
  Odd = 2
}

public static Evenness AnalyzeEvenness(object o)
{

  if (o == null)
    return Evenness.Unknown;

  string foo = o.ToString();

  if (String.IsNullOrEmpty(foo))
    return Evenness.Unknown;

  char bar = foo[foo.Length - 1];

  switch (bar)
  {
     case '0':
     case '2':
     case '4':
     case '6':
     case '8':
       return Evenness.Even;
     case '1':
     case '3':
     case '5':
     case '7':
     case '9':
       return Evenness.Odd;
     default:
       return Evenness.Unknown;
  }
}

[Joke mode="off"]

EDIT: Added confusing values to the enum.

In response to ffpf - I had exactly the same argument with a colleague years ago, and the answer is no, it doesn't work with negative numbers.

The C standard stipulates that negative numbers can be represented in 3 ways:

  • 2's complement
  • 1's complement
  • sign and magnitude

Checking like this:

isEven = (x & 1);

will work for 2's complement and sign and magnitude representation, but not for 1's complement.

However, I believe that the following will work for all cases:

isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));

Thanks to ffpf for pointing out that the text box was eating everything after my less than character!

A nice one is:

/*forward declaration, C compiles in one pass*/
bool isOdd(unsigned int n);

bool isEven(unsigned int n)
{
  if (n == 0) 
    return true ;  // I know 0 is even
  else
    return isOdd(n-1) ; // n is even if n-1 is odd
}

bool isOdd(unsigned int n)
{
  if (n == 0)
    return false ;
  else
    return isEven(n-1) ; // n is odd if n-1 is even
}

Note that this method use tail recursion involving two functions. It can be implemented efficiently (turned into a while/until kind of loop) if your compiler supports tail recursion like a Scheme compiler. In this case the stack should not overflow !

A number is even if, when divided by two, the remainder is 0. A number is odd if, when divided by 2, the remainder is 1.

// Java
public static boolean isOdd(int num){
    return num % 2 != 0;
}

/* C */
int isOdd(int num){
    return num % 2;
}

Methods are great!

I'd say just divide it by 2 and if there is a 0 remainder, it's even, otherwise it's odd.

Using the modulus (%) makes this easy.

eg. 4 % 2 = 0 therefore 4 is even 5 % 2 = 1 therefore 5 is odd

One more solution to the problem
(children are welcome to vote)

bool isEven(unsigned int x)
{
  unsigned int half1 = 0, half2 = 0;
  while (x)
  {
     if (x) { half1++; x--; }
     if (x) { half2++; x--; }

  }
  return half1 == half2;
}

I would build a table of the parities (0 if even 1 if odd) of the integers (so one could do a lookup :D), but gcc won't let me make arrays of such sizes:

typedef unsigned int uint;

char parity_uint [UINT_MAX];
char parity_sint_shifted [((uint) INT_MAX) + ((uint) abs (INT_MIN))];
char* parity_sint = parity_sint_shifted - INT_MIN;

void build_parity_tables () {
    char parity = 0;
    unsigned int ui;
    for (ui = 1; ui <= UINT_MAX; ++ui) {
        parity_uint [ui - 1] = parity;
        parity = !parity;
    }
    parity = 0;
    int si;
    for (si = 1; si <= INT_MAX; ++si) {
        parity_sint [si - 1] = parity;
        parity = !parity;
    }
    parity = 1;
    for (si = -1; si >= INT_MIN; --si) {
        parity_sint [si] = parity;
        parity = !parity;
    }
}

char uparity (unsigned int n) {
    if (n == 0) {
        return 0;
    }
    return parity_uint [n - 1];
}

char sparity (int n) {
    if (n == 0) {
        return 0;
    }
    if (n < 0) {
        ++n;
    }
    return parity_sint [n - 1];
}

So let's instead resort to the mathematical definition of even and odd instead.

An integer n is even if there exists an integer k such that n = 2k.

An integer n is odd if there exists an integer k such that n = 2k + 1.

Here's the code for it:

char even (int n) {
    int k;
    for (k = INT_MIN; k <= INT_MAX; ++k) {
        if (n == 2 * k) {
            return 1;
        }
    }
    return 0;
}

char odd (int n) {
    int k;
    for (k = INT_MIN; k <= INT_MAX; ++k) {
        if (n == 2 * k + 1) {
            return 1;
        }
    }
    return 0;
}

Let C-integers denote the possible values of int in a given C compilation. (Note that C-integers is a subset of the integers.)

Now one might worry that for a given n in C-integers that the corresponding integer k might not exist within C-integers. But with a little proof it is can be shown that for all integers n, |n| <= |2n| (*), where |n| is "n if n is positive and -n otherwise". In other words, for all n in integers at least one of the following holds (exactly either cases (1 and 2) or cases (3 and 4) in fact but I won't prove it here):

Case 1: n <= 2n.

Case 2: -n <= -2n.

Case 3: -n <= 2n.

Case 4: n <= -2n.

Now take 2k = n. (Such a k does exist if n is even, but I won't prove it here. If n is not even then the loop in even fails to return early anyway, so it doesn't matter.) But this implies k < n if n not 0 by (*) and the fact (again not proven here) that for all m, z in integers 2m = z implies z not equal to m given m is not 0. In the case n is 0, 2*0 = 0 so 0 is even we are done (if n = 0 then 0 is in C-integers because n is in C-integer in the function even, hence k = 0 is in C-integers). Thus such a k in C-integers exists for n in C-integers if n is even.

A similar argument shows that if n is odd, there exists a k in C-integers such that n = 2k + 1.

Hence the functions even and odd presented here will work properly for all C-integers.

This is a follow up to the discussion with @RocketRoy regarding his answer, but it might be useful to anyone who wants to compare these results.

tl;dr From what I've seen, Roy's approach ((0xFFFFFFFF == (x | 0xFFFFFFFE)) is not completely optimized to x & 1 as the mod approach, but in practice running times should turn out equal in all cases.

So, first I compared the compiled output using Compiler Explorer:

Functions tested:

int isOdd_mod(unsigned x) {
    return (x % 2);
}

int isOdd_and(unsigned x) {
    return (x & 1);
}

int isOdd_or(unsigned x) {
    return (0xFFFFFFFF == (x | 0xFFFFFFFE));
}   

CLang 3.9.0 with -O3:

isOdd_mod(unsigned int):                          # @isOdd_mod(unsigned int)
        and     edi, 1
        mov     eax, edi
        ret

isOdd_and(unsigned int):                          # @isOdd_and(unsigned int)
        and     edi, 1
        mov     eax, edi
        ret

isOdd_or(unsigned int):                           # @isOdd_or(unsigned int)
        and     edi, 1
        mov     eax, edi
        ret

GCC 6.2 with -O3:

isOdd_mod(unsigned int):
        mov     eax, edi
        and     eax, 1
        ret

isOdd_and(unsigned int):
        mov     eax, edi
        and     eax, 1
        ret

isOdd_or(unsigned int):
        or      edi, -2
        xor     eax, eax
        cmp     edi, -1
        sete    al
        ret

Hats down to CLang, it realized that all three cases are functionally equal. However, Roy's approach isn't optimized in GCC, so YMMV.

It's similar with Visual Studio; inspecting the disassembly Release x64 (VS2015) for these three functions, I could see that the comparison part is equal for "mod" and "and" cases, and slightly larger for the Roy's "or" case:

// x % 2
test bl,1  
je (some address) 

// x & 1
test bl,1  
je (some address) 

// Roy's bitwise or
mov eax,ebx  
or eax,0FFFFFFFEh  
cmp eax,0FFFFFFFFh  
jne (some address)

However, after running an actual benchmark for comparing these three options (plain mod, bitwise or, bitwise and), results were completely equal (again, Visual Studio 2005 x86/x64, Release build, no debugger attached).

Release assembly uses the test instruction for and and mod cases, while Roy's case uses the cmp eax,0FFFFFFFFh approach, but it's heavily unrolled and optimized so there is no difference in practice.

My results after 20 runs (i7 3610QM, Windows 10 power plan set to High Performance):

[Test: Plain mod 2 ] AVERAGE TIME: 689.29 ms (Relative diff.: +0.000%)
[Test: Bitwise or  ] AVERAGE TIME: 689.63 ms (Relative diff.: +0.048%)
[Test: Bitwise and ] AVERAGE TIME: 687.80 ms (Relative diff.: -0.217%)

The difference between these options is less than 0.3%, so it's rather obvious the assembly is equal in all cases.

Here is the code if anyone wants to try, with a caveat that I only tested it on Windows (check the #if LINUX conditional for the get_time definition and implement it if needed, taken from this answer).

#include <stdio.h>

#if LINUX
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
    struct timeval t;
    struct timezone tzp;
    gettimeofday(&t, &tzp);
    return t.tv_sec + t.tv_usec*1e-6;
}
#else
#include <windows.h>
double get_time()
{
    LARGE_INTEGER t, f;
    QueryPerformanceCounter(&t);
    QueryPerformanceFrequency(&f);
    return (double)t.QuadPart / (double)f.QuadPart * 1000.0;
}
#endif

#define NUM_ITERATIONS (1000 * 1000 * 1000)

// using a macro to avoid function call overhead
#define Benchmark(accumulator, name, operation) { \
    double startTime = get_time(); \
    double dummySum = 0.0, elapsed; \
    int x; \
    for (x = 0; x < NUM_ITERATIONS; x++) { \
        if (operation) dummySum += x; \
    } \
    elapsed = get_time() - startTime; \
    accumulator += elapsed; \
    if (dummySum > 2000) \
        printf("[Test: %-12s] %0.2f ms\r\n", name, elapsed); \
}

void DumpAverage(char *test, double totalTime, double reference)
{
    printf("[Test: %-12s] AVERAGE TIME: %0.2f ms (Relative diff.: %+6.3f%%)\r\n",
        test, totalTime, (totalTime - reference) / reference * 100.0);
}

int main(void)
{
    int repeats = 20;
    double runningTimes[3] = { 0 };
    int k;

    for (k = 0; k < repeats; k++) {
        printf("Run %d of %d...\r\n", k + 1, repeats);
        Benchmark(runningTimes[0], "Plain mod 2", (x % 2));
        Benchmark(runningTimes[1], "Bitwise or", (0xFFFFFFFF == (x | 0xFFFFFFFE)));
        Benchmark(runningTimes[2], "Bitwise and", (x & 1));
    }

    {
        double reference = runningTimes[0] / repeats;
        printf("\r\n");
        DumpAverage("Plain mod 2", runningTimes[0] / repeats, reference);
        DumpAverage("Bitwise or", runningTimes[1] / repeats, reference);
        DumpAverage("Bitwise and", runningTimes[2] / repeats, reference);
    }

    getchar();

    return 0;
}

I know this is just syntactic sugar and only applicable in .net but what about extension method...

public static class RudiGroblerExtensions
{
    public static bool IsOdd(this int i)
    {
        return ((i % 2) != 0);
    }
}

Now you can do the following

int i = 5;
if (i.IsOdd())
{
    // Do something...
}

In the "creative but confusing category" I offer:

int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }

A variant on this theme that is specific to Microsoft C++:

__declspec(naked) bool __fastcall isOdd(const int x)
{
    __asm
    {
        mov eax,ecx
        mul eax
        mul eax
        mul eax
        mul eax
        mul eax
        mul eax
        ret
    }
}

The bitwise method depends on the inner representation of the integer. Modulo will work anywhere there is a modulo operator. For example, some systems actually use the low level bits for tagging (like dynamic languages), so the raw x & 1 won't actually work in that case.

IsOdd(int x) { return true; }

Proof of correctness - consider the set of all positive integers and suppose there is a non-empty set of integers that are not odd. Because positive integers are well-ordered, there will be a smallest not odd number, which in itself is pretty odd, so clearly that number can't be in the set. Therefore this set cannot be non-empty. Repeat for negative integers except look for the greatest not odd number.

Portable:

i % 2 ? odd : even;

Unportable:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;
int isOdd(int i){
  return(i % 2);
}

done.

For the sake of discussion...

You only need to look at the last digit in any given number to see if it is even or odd. Signed, unsigned, positive, negative - they are all the same with regards to this. So this should work all round: -

void tellMeIfItIsAnOddNumberPlease(int iToTest){
  int iLastDigit;
  iLastDigit = iToTest - (iToTest / 10 * 10);
  if (iLastDigit % 2 == 0){
    printf("The number %d is even!\n", iToTest);
  } else {
    printf("The number %d is odd!\n", iToTest);
  }
}

The key here is in the third line of code, the division operator performs an integer division, so that result are missing the fraction part of the result. So for example 222 / 10 will give 22 as a result. Then multiply it again with 10 and you have 220. Subtract that from the original 222 and you end up with 2, which by magic is the same number as the last digit in the original number. ;-) The parenthesis are there to remind us of the order the calculation is done in. First do the division and the multiplication, then subtract the result from the original number. We could leave them out, since the priority is higher for division and multiplication than of subtraction, but this gives us "more readable" code.

We could make it all completely unreadable if we wanted to. It would make no difference whatsoever for a modern compiler: -

printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");

But it would make the code way harder to maintain in the future. Just imagine that you would like to change the text for odd numbers to "is not even". Then someone else later on want to find out what changes you made and perform a svn diff or similar...

If you are not worried about portability but more about speed, you could have a look at the least significant bit. If that bit is set to 1 it is an odd number, if it is 0 it's an even number. On a little endian system, like Intel's x86 architecture it would be something like this: -

if (iToTest & 1) {
  // Even
} else {
  // Odd
}

If you want to be efficient, use bitwise operators (x & 1), but if you want to be readable use modulo 2 (x % 2)

+66% faster > !(i%2) / i%2 == 0

int isOdd(int n)
{
    return n & 1;
}

The code checks the last bit of the integer if it's 1 in Binary

Explanation

Binary  :   Decimal
-------------------
0000    =   0
0001    =   1
0010    =   2
0011    =   3
0100    =   4
0101    =   5
0110    =   6
0111    =   7
1000    =   8
1001    =   9
and so on...

Notice the rightmost bit is always 1 for Odd numbers.

the & bitwise AND operator checks the rightmost bit in our return line if it's 1

Think of it as true & false

When we compare n with 1 which means 0001 in binary (number of zeros doesn't matter).
then let's just Imagine that we have the integer n with a size of 1 byte.

It'd be represented by 8-bit / 8-binary digits.

If the int n was 7 and we compare it with 1, It's like

7 (1-byte int)|    0  0  0  0    0  1  1  1
       &
1 (1-byte int)|    0  0  0  0    0  0  0  1
********************************************
Result        |    F  F  F  F    F  F  F  T

Which F stands for false and T for true.

It compares only the rightmost bit if they're both true. So, automagically 7 & 1 is True.

What if I want to check the bit before the rightmost?

Simply change n & 1 to n & 2 which 2 represents 0010 in Binary and so on.

I suggest using hexadecimal notation if you're a beginner to bitwise operations
return n & 1; >> return n & 0x01;.

Related