views:

12816

answers:

23

How best can I check if an integer is even or odd in C? I considered how I'd do this in Java, but I couldn't come up with an answer either. Thanks.

+5  A: 

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

Jarod Elliott
+156  A: 

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.

Chris Young
For Java this has to be: if (x % 2 == 0) { /* x is odd */ } As integers are not automatically treated as boolean in if statements
Philip Fourie
The question specifically asked how to do it in C so I answered it in C, despite chustar mentioning they couldn't work out how to do it in Java. I did not claim or imply this was a Java answer, I do not know Java. I think I just got my first downvote and am confused as to why. Oh well.
Chris Young
I'd say, if (x % 2 != 0) { /* x is odd */ }, but who knows. Do not know java either.
eugensk00
Chris Young
Aaron
Up Vote! I prefer the modulo version, Some people are going have to ask questions or consult a reference for the bit arithmetic.
Brian G
This got upvoted over 30 times and only one person has noted that "/* x is odd */" should be "/* x is even */". Interesting.
Joel B Fant
Joel B Fant: you'd better check again, my answer is correct. What baffles me is that I got downvoted 4 times.
Chris Young
34 upvotes to explain modulo? No offense, but I feel like we've had plenty more tricky questions...and more elaborate answers. Although this is correct and obviously a point of great discussion...
Codewerks
Chris Young: Sorry, you're right. I think I had the (x % 2 == 0) {/*x is odd*/} comment stuck in my head.
Joel B Fant
That is awesome that that optimization is in there.
Daniel A. White
It's getting lots of upvotes to distinguish it from the bitwise operator morons, without having to spend our karma voting them down.
wnoise
I tested with SDCC, and the bitwise version gives a LOT more compact and fast code.
matli
most good optimizing compilers will generate exactly the same code for 'and 1' as for 'mod 2'. Personally I would code it using bitwise but either works.
KPexEA
I agree with everything, except one thing: I like to keep integers and truth values separate, conceptually, so I prefer to write "if (x % 2 == 1)". It's the same to the compiler, but perhaps a bit clearer to humans. Plus you can use the same code in languages that don't interpret non-zero as true.
Thomas Padron-McCarthy
+1 for the superior answer, and the depth of research. Thanks!
Bobby Jack
im going to upvote you. nice answer
Johannes Schaub - litb
Good answer but your benchmark is not well-designed. `printf` is the most time consuming part of it (and is an IO-bound operation). This will degrade the accuracy of the benchmark.
Mehrdad Afshari
My benchmark? What benchmark? I didn't do any benchmarking. I examined the generated assembly language. This has absolutely nothing to do with printf.
Chris Young
+1 for your benchmarking and considerations of different representations in memory
Kirschstein
+1 for a great answer. FWIW, I prefer the readability of this answer to the bit arithmetic answer. Seems more understandable for coders seeing it after I'm gone.
Steve Duitsman
"two's complement is somewhat ubiquitous" ? how can you have ubiquitous, but "somewhat"?
動靜能量
Jian Lin: ubiquitous means it occurs everywhere, so I use "somewhat ubiquitous" to mean that it's almost occurring everywhere. Sorry if it was unclear.
Chris Young
+3  A: 
i % 2 == 0
Mark Cidade
+39  A: 

Use bit arithmetic:

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

This is faster than using division or modulus.

Adam Pierce
That's exactly what I just posted. Up vote for having a great mind. ;)
Jeff Yates
I don't think it's fair to say it's faster than using division or modulus. The C standard doesn't say anything about performance of operators, and any decent compiler will produce fast code for either. I would personally choose the idiom that communicates my intent, and % seems more appropriate here
Chris Young
I agree with Chris Young - I believe that any modern C/C++ compiler will boil the "% 2" operation down to a bit test. At least for non-debug builds.
Michael Burr
yjerem
I like the bitwise method for similar reasoning. It also feels more elegant, not that one should get points for elegance, necessarily.
Jeff Yates
You're right, I guess it's subjective. Though the usual definition of "even" is "integer that's divisible by 2", not "integer that ends in 0, 2, 4, 6 or 8". :-)
Chris Young
Wouldn't it be reversed if it were a negative int?
TraumaPony
bleh, sacrificing clear intent for "cleverness". Talk about premature optimisation...
freespace
@TraumaPony - for ANSI standard C and early Java, depends on the computer system. It's unspecified what representation is used for signed numbers -- 2's compliment, 1's compliment, grey-coded, etc. But modulus is always modulus
Aaron
Doesn't work universally for negative numbers. See Check this answer for more detail: http://stackoverflow.com/questions/160930/how-do-i-check-if-an-integer-is-even-or-odd#161326 for details.
Andrew Edgecombe
The bitmask-solution depends on internal representation of the number. While it's usual today to use Two's complement, it's not given, that it persists in the future. So use the modulo-operator, and your code is always correct. Good compilers optimize it anyways.
Mnementh
The bitmask solution will give 0 (even) or 1 (odd) on all non-museum piece computers. Modulo gives 0 (even) or 1 (+ve odd) or -1 (-ve odd) throughout the commonest x86 computers. And the beloved standard says it can return either plus or minus 1 when doing the mod 2 of a negative number.
paperhorse
+/-1 is still not 0 so its a moot point.
freespace
Note that this method requires knowledge of the internal structure of the types at hand, whereas modulus does not.
trinithis
+4  A: 
// C#
bool isEven = ((i % 2) == 0);
Michael Petrotta
What? That's not C#! That's pure C! :-P
asterite
I'll throw a WinForm around it to make it pure C#...
Michael Petrotta
bool in pure C?
mateusza
@mateusza: Usually when you see "bool" in some capitalization or other in C, it's a `typedef` or `#define` or something.
David Thornley
@mateusza @David Thornley In C99 bool is a standard feature (http://en.wikipedia.org/wiki/Stdbool.h)
fortran
+9  A: 

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!

jjnguy
Your Java method is broken because num % 2 == -1 for negative odd numbers.
WMR
Is that why you downvoted me?
jjnguy
I downvoted it because your function in C takes more characters to type than what it does. IEnum % I is 7 characters including the spacesIsOdd(I) is 8 characters. Why would you create a function that is longer than just doing the operation?
Kevin
Instead of invoking abs(), just compare != 0.
Mattias Andersson
+2  A: 

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.

Will Hartung
+47  A: 

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...

SCdF
Up vote for making me grin first thing in the morning. Stackoverflow should give a badge for worst conceiveable answer / most entertaining answer.
Shane MacLaughlin
Funny, this is, but I don't agree in upvoting clearly demented solutions :-). Still, I'm not going to waste karma downvoting...
paxdiablo
SO needs a "WTF?" flag as well as "offensive?", that would fix it :)
Tom
Brilliant - positively *enterprisey*
Duncan Smart
I have to agree... interesting, but little demented. If this were slashdot, you'd get an upvote for funny. I can't recommend this solution though :)
Wes P
If you threw an argument exception on negative values, and noted in the documentation that this function is O(N), then I would just fine with this.
Jeffrey L Whitledge
Up voted for making me smile.
Cristian Ciupitu
Jeffrey: awesome.
Michael Haren
I bet you write LOL code for a living :)
Kris
Works with negative integers if you do `num = abs (num)`.
trinithis
The enterprise version would have to use XML. Of course nowadays you would have a web service that you could query
Martin Beckett
Really Brilliant! I wish I could write that code!
fastcodejava
You should optimise this with a look-up table.
Weeble
@Weeble: See my post.
trinithis
+4  A: 

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;
}
eugensk00
true but overkill
Nathan Fellman
No, you are not the kind of child I counted on :)
eugensk00
I was going to upvote this, but it's a bit slow on negative numbers. :)
Chris Young
All numbers are bright and positive. Or are you prejudiced against some? :))
eugensk00
In computers, all numbers once negative, eventually become positive. We call it the Rollover of Happiness (not applicable to BIGNUMS, YMMY, not valid in all states).
Will Hartung
+6  A: 

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 compliment - 1's compliment - "sign and magnitude".

Checking like this:

  isEven = (x & 1);

will work for 2's compliment and sign and magnitude formats, but not for 1's compliment.

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

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

edit: thanks to ffpf for pointing out that the text box was eating everything after my lessthan character!

Andrew Edgecombe
I think your second code example is missing some text.
Jeff Yates
+7  A: 

A nice one is:

bool isEven(unsigned int n)
{
  if (n == 0) 
    return true ;  // I know 0 is even
  else if (n == 1)
    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 !

Pierre
This does not handle isOdd(0) well.
Steve McLeod
I think you've got an infinite loop (with tail recursion) or a stack overflow (without tail recursion) for isOdd() with any even values or isEven() with any odd values. It only terminates with true. It's the halting problem all over again.
Jeffrey L Whitledge
Oh, sure, fix it with no comment, and make me look like an idiot. That's fine.
Jeffrey L Whitledge
Now, you've got a compile error: in isEven not all code paths return a value.No, I haven't actually tried this code, it's the compiler in my head that's complaining.
Jeffrey L Whitledge
@Jeffrey Sorry about the fix with no comment. Did not want to make you look like an idiot. You are quite good for finding out the bug. Next time I'll do better.
Pierre
compile error: not all paths return a valuehate to bombard you with bug comments on your sample code, but what happens when you call isEven(5)
Kevin
LEGIT!!!!!!!!!!!!!!!!!!!!! (Edit: Note that isEven only recurses in the case n == 1 as it is now.)
trinithis
+3  A: 

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...
}
rudigrobler
Nice code. Pity that it will claim that 2 is odd, and 3 is not.
Anthony
oops, sorry... my logic is wrong way round...
rudigrobler
+17  A: 

[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.

Sklivvz
Wow... this is more demented than SCdF's solution! Kudos! No upvote though... can't recommend this. But thanks for the funny!
Wes P
The advantage of this approach is it works with more than just numbers. Also, if you replace this line:char bar = foo[foo.Length - 1];with this:double bar = Char.GetNumericValue(foo[foo.Length - 1]);Then it will work with any number system.
Jeffrey L Whitledge
made me laugh out - frickin - loud
Kris
bug report: 14.65 is reported as odd when it should be unknown.
TheSoftwareJedi
Software Jedi, it's a "feature". ;)
Sklivvz
TheSoftwareJedi: 14.65 is one of the oddest integers I've ever seen.
Bruce Alderman
Uh... this doesn't work with all base representations :D... well it DOES work... just <em>maybe</em> not as intended.
trinithis
the op is asking about C (or maybe Java), not C# :-p
fortran
+1  A: 

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.

plinth
+1  A: 

Portable:

i % 2 ? odd : even;

Unportable:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;
ilitirit
+1  A: 
    MOV EAX, VALUE_TO_TEST
    AND EAX, 01
    JNZ VALUE_ODD
VALUE_EVEN:
    // Even code goes here
    JMP DONE:
VALUE_ODD:
    // Odd code goes here
DONE:
Jeffrey L Whitledge
Something tells me that a person who doesn't know how to check if a number is odd probably doesn't know assembly...
Michael Myers
Or how integers are implemented in C.
Arthur Kalliokoski
The references to C in the question and in the tags were added long after this question was first asked. Originally, there was no reference to any programming language, so a few of us just guessed at what the OP was using.
Jeffrey L Whitledge
+1  A: 

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
}
Tooony
What exactly is wrong with just going iToTest%2==0? You are wasting a division extracting the last digit, so yours is twice as slow as it needs to be.
freespace
@freespace: I waste more than that, don't I? :-) A multiplication and a subtraction too. But what is most efficient between the two solutions I don't dare to say. Never claimed this to be the fastest solution, quite the opposite if you read the first line of my post again.
Tooony
@Tooony, ah, my humour hat fell off. It is formly back on now :D Sorry about that :)
freespace
+1  A: 

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

Vihung
+1  A: 

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
 }
}
DocMax
+1  A: 
int isOdd(int i){
  return(i % 2);
}

done.

Mark Lubin
A: 

in c language

main()

{

int n;

clrscr();

printf("enter integer value: ");

scanf("%d",&n);

if(n%2= =0)

printf("given value is even");

if(n%2!=0)

printf("given value is odd");

}

basher
what is `= =` in C?
trinithis
`clrscr` is not part of the language, AFAIK.
GMan
+2  A: 

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.

trinithis
I don't mean offense, but what's the point of this answer? `i % 2` is much smaller and probably more efficient.
GMan
@GMan: But this is way more deterministic! This will work correctly detect all edge cases.
P Daddy
... AND (!!!) it is correct!!!
trinithis
I can't tell if you're joking or not. :X `%2` works for all integers.
GMan
This post is a joke.
trinithis
A: 

// to determine the biggest of three numbers entered by the user.

include

using namespace std; int main()

{ int num; cout <<"\t enter the number \t";
cin>>num; if(num%==0); cout<<" the number is even ";

else
cout<< "\t the number is odd " ;
return 0;

}

rajat