views:

698

answers:

11

What is the fastest way to find if a number is even or odd?

+2  A: 
int i=5;
if ( i%2 == 0 )
{
   // Even
} else {
   // Odd
}
lamas
Checking the least significant bit would be faster than the modulus operator. However, I bet most compilers would turn "mod 2" into "and 1"
bramp
@bramp: they can't if `i` is signed.
R..
@R: are you sure? For example, the twos complement of 127 is "01111111", and -127 is "10000001", both have the least significant bit set.
bramp
+3  A: 

if (x & 1) is true then it's odd, otherwise it's even.

Vicky
This fails on a machine using one's complement.
Jason
Also, and this is a general comment to all the answers to date, the question did not specify the number was an integer. You can't do bitwise operations on floats (at least, not without some type-casting hackery).
Skizz
@Skizz: Define even or oddness for a non-integer.
dmckee
Skizz
@Skizz you can define it for 2.0 *because* it has an integer expression. So, the right thing to do is convert to int and handle the result as discussed.
dmckee
+2  A: 

If it's an integer, probably by just checking the least significant bit. Zero would be counted as even though.

Marcel
+1 Good one on zero.
Tom
Zero is an even number. This also fails on a machine using one's complement.
Jason
+6  A: 
bool is_odd = number & 1;
digitalarbeiter
thats fast, but wont compile unless there's a typedef somewhere
Tom
This fails on a machine using one's complement.
Jason
@Jason: You're right of course, this implementation implies two's complement logic. I'm not aware of any contemporary one's complement hardware, however. If you know of any, please comment.
digitalarbeiter
Jim Buck
@Jason, you can create a function to check if the machine is ones or twos compliment. But im too lazy to thing now
medopal
@Jason: it succeeds on a machine using ones complement if you change the `1` to `1U`.
R..
+1  A: 

Check to see if the last bit is 1.

int is_odd(int num) {
  return num & 1;
}
0xfe
See the comment of Tom, same applies here. This won't compile in C.
AndiDog
Right... changed to int. (FWIW, some build environments #define or typedef bool to int).
0xfe
+1  A: 

Check the least significant bit:

if (number & 0x01) {
  // It's odd
} else {
  // It's even
}
holygeek
Out of curiosity: Why `0x01` instead of simply `1`?
Joachim Sauer
It's habit. I'm used to *always* using hexadecimal representation when doing bitwise operations :)
holygeek
+6  A: 

Usual way to do it:

int number = ...;
if(number % 2) { odd }
else { even }

Alternative:

int number = ...;
if(number & 1) { odd }
else { even }

Tested on GCC 3.3.1 and 4.3.2, both have about the same speed (without compiler optimization) as both result in the and instruction (compiled on x86) - I know that using the div instruction for modulo would be much slower, thus I didn't test it at all.

AndiDog
The compiler has likely removed the test completely as the are both probably constant. Recall that `gcc` without options is equivalent to `gcc -O2` which is a non-trivial level of speed optimization. Check the generated assembly to be sure..
dmckee
Isn't bitwise-XOR more faster than bitwise-AND? Is it not possible with XOR operation?
aks
@dmckee: I don't know why you think level 2 was the default. The man page clearly says "-O0 Do not optimize. This is the default.". But I checked the assembly code anyway and it was not removed from the code (that's why it takes 7 seconds for each test to run).
AndiDog
@aks: I tested bitwise XOR and it's at the very same speed as AND/modulo (BTW these two produce the same code on x86, namely an "and" instruction). Anyway could you tell me how to determine odd/even with *only* an XOR statement?
AndiDog
@AndiDog InRe optimization levels: Mea Cupla.
dmckee
A: 

Your question is not completely specified. Regardless, the answer is dependent on your compiler and the architecture of your machine. For example, are you on a machine using one's complement or two's complement signed number representations?

I write my code to be correct first, clear second, concise third and fast last. Therefore, I would code this routine as follows:

/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
    return n % 2 == 0;
}

This method is correct, it more clearly expresses the intent than testing the LSB, it's concise and, believe it or not, it is blazing fast. If and only if profiling told me that this method were a bottleneck in my application would I consider deviating from it.

Jason
@unwind: I'm pretty sure there is, and has been for more than 10 years (since C99)
static_rtti
@UpvoteRemover: What gives?
Jason
+2  A: 
int is_odd(int n)
{
   if (n == 0)
      return 0;
   else if (n == 1)
      return 1;
   else
      return !is_odd(n - 1);
}

Oh wait, you said fastest way, not funniest. My bad ;)

Above function only works for positive numbers of course.

Maurits Rijk
I would perform a prime factorization on *n*, then check whether it has any factors if 2. :p
KennyTM
what about: int is_odd(int n) { return cos(M_PI * n) < 0.0; }
e.tadeu
A good compiler should output the same assembler as with `{return n }` :)
static_rtti
It's a good test for compiler "goodness"
e.tadeu
+1  A: 

The portable way is to use the modulus operator %:

if (x % 2 == 0) // number is even

If you know that you're only ever going to run on two's complement architectures, you can use a bitwise and:

if (x & 0x01 == 0) // number is even

Using the modulus operator can result in slower code relative to the bitwise and; however, I'd stick with it unless all of the following are true:

  1. You are failing to meet a hard performance requirement;
  2. You are executing x % 2 a lot (say in a tight loop that's being executed thousands of times);
  3. Profiling indicates that usage of the mod operator is the bottleneck;
  4. Profiling also indicates that using the bitwise-and relieves the bottleneck and allows you to meet the performance requirement.
John Bode
KennyTM
Plus you should check if the compiler really outputs different machine code for the two. My bet is that it should output the same, especially with optimizations turned on.
static_rtti
+15  A: 

It is pretty well known that

static inline int is_odd_A(int x) { return x & 1; }

is more efficient than

static inline int is_odd_B(int x) { return x % 2; }

But with the optimizer on, will is_odd_B be no different from is_odd_A? No — with gcc-4.2 -O2, we get, (in ARM assembly):

_is_odd_A:
    and r0, r0, #1
    bx  lr

_is_odd_B:
    mov r3, r0, lsr #31
    add r0, r0, r3
    and r0, r0, #1
    rsb r0, r3, r0
    bx  lr

We see that is_odd_B takes 3 more instructions than is_odd_A, the main reason is because

((-1) % 2) == -1
((-1) & 1) ==  1

However, all the following versions will generate the same code as is_odd_A:

#include <stdbool.h>
static inline bool is_odd_D(int x) { return x % 2; }      // note the bool
static inline int  is_odd_E(int x) { return x % 2 != 0; } // note the !=

What does this mean? The optimizer is usually sophisticated enough that, for these simple stuff, the clearest code is enough to guarantee best efficiency.

KennyTM
even better, specify the argument as `unsigned`.
Potatoswatter
R..