ChatGPT解决这个技术问题 Extra ChatGPT

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

Closed. This question needs to be more focused. It is not currently accepting answers. Closed 4 years ago. Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.

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

The version that uses bitwise and (&) is much more efficient than the modulo (%) version. You should change the one you selected as the correct answer.
Unlikely to matter - argument is a constant. Easy for the optimizer
Readability factors into this as well.
In embedded applications (the world where I spend most of my programming time), some processors have very primitive arithmetic units and cannot do division/modulus operations easily. For this reason, I usually use the bitwise-and method instead. However, on a modern desktop's CPU this won't be the case.
I've never found the modulus operation to be easier to understand. When I first needed to determine even or odd, the bitwise mask was the first thing that came to mind. It's somewhat natural, since the way we tend to do this by hand is to look at the least significant digit to see if it's in {0 2 4 6 8} or {1 3 5 7 9}. That translates directly to looking at the least significant bit to see if it's 0 or 1.

C
Chris Young

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.


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.
I'd say, if (x % 2 != 0) { /* x is odd */ }, but who knows. Do not know java either.
It's getting lots of upvotes to distinguish it from the bitwise operator morons, without having to spend our karma voting them down.
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.
My benchmark? What benchmark? I didn't do any benchmarking. I examined the generated assembly language. This has absolutely nothing to do with printf.
b
brimborium

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


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.
The enterprise version would have to use XML. Of course nowadays you would have a web service that you could query
You should optimise this with a look-up table.
I'm such a monk, had to +1 your 6,999 rep into a new millennium
This is brilliant! My boss told me we had a client that was angry because he felt his Enterprise License wasn't giving anything more than the Standard License. Now we've added this function in our program, and just because it executes more slowly, he think his software is doing WAY more work!!!
A
Adam Pierce

Use bit arithmetic:

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

This is faster than using division or modulus.


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
I like (x & 1) better, because it checks whether the number is even the same way people do: check if the last digit is even or odd. In my opinion it communicates its intent more than the modulo method. (Not that it matters much.)
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". :-)
@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
Doesn't work universally for negative numbers. See Check this answer for more detail: stackoverflow.com/questions/160930/… for details.
S
Sklivvz

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


Wow... this is more demented than SCdF's solution! Kudos! No upvote though... can't recommend this. But thanks for the funny!
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.
bug report: 14.65 is reported as odd when it should be unknown.
Software Jedi, it's a "feature". ;)
TheSoftwareJedi: 14.65 is one of the oddest integers I've ever seen.
C
Community

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!


I think your second code example is missing some text.
Let's compliment those numbers!
f
fortran

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 !


This does not handle isOdd(0) well.
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.
Oh, sure, fix it with no comment, and make me look like an idiot. That's fine.
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.
compile error: not all paths return a value hate to bombard you with bug comments on your sample code, but what happens when you call isEven(5)
j
jjnguy

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!


Your Java method is broken because num % 2 == -1 for negative odd numbers.
Is that why you downvoted me?
I downvoted it because your function in C takes more characters to type than what it does. IE num % I is 7 characters including the spaces IsOdd(I) is 8 characters. Why would you create a function that is longer than just doing the operation?
@Kevin in my opinion code is not measured by chars but rather by the time it takes you to write it, including think + debug time. num % 2 takes a millisecond more to think of than isOdd. now add the numbers globally and you lost a collective year. also isOdd can be tested, and verified and eventually bug free certified (e.g. handling negative numbers) where as num % 2 - some developers will always have a doubt and go experimenting. good code is code you don't write, just reuse... just my 2 cents.
@EranMedan, The same logic would apply to replacing i++ with IncrementByOne(i) and it is just as bad an idea. If a developer has doubt about what num % 2 does, I don't want him or her anywhere near my code.
M
Mark Cidade
i % 2 == 0

J
Jarod Elliott

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


e
eugensk

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

No, you are not the kind of child I counted on :)
I was going to upvote this, but it's a bit slow on negative numbers. :)
All numbers are bright and positive. Or are you prejudiced against some? :))
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).
@WillHartung "rollover of happiness" is great! :D
T
Thomas Eding

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.


I don't mean offense, but what's the point of this answer? i % 2 is much smaller and probably more efficient.
@GMan: But this is way more deterministic! This will work correctly detect all edge cases.
... AND (!!!) it is correct!!!
I can't tell if you're joking or not. :X %2 works for all integers.
+1: I was gonna say "Good Answer", but I think "Interesting Answer" is more appropriate.
M
Michael Petrotta
// C#
bool isEven = ((i % 2) == 0);

What? That's not C#! That's pure C! :-P
I'll throw a WinForm around it to make it pure C#...
@mateusza: Usually when you see "bool" in some capitalization or other in C, it's a typedef or #define or something.
@mateusza @David Thornley In C99 bool is a standard feature (en.wikipedia.org/wiki/Stdbool.h)
Talk about hugely redundant parentheses...
o
octopusgrabbus

Here is an answer in Java:

public static boolean isEven (Integer Number) {
    Pattern number = Pattern.compile("^.*?(?:[02]|8|(?:6|4))$");
    String num = Number.toString(Number);
    Boolean numbr = new Boolean(number.matcher(num).matches());
    return numbr.booleanValue();
}

K
Kiril Aleksandrov

Try this: return (((a>>1)<<1) == a)

Example:

a     =  10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010

b     =  10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100

Can you explain this please? I'm very unfamiliar with bitwise operators
Shifting right and then left will zero your last bit (the most right one). If the new number is the same as the original, this means that the last bit of the original number was 0. So it is even. Take a look at my updated answer.
thanks, I get it now
I'm not sure which approach is faster. I haven't tried to benchmark them.
Doesn't this also zero out your most significant bit? An issue with unsigned ints in some languages and negative ints in most...
佚名

Reading this rather entertaining discussion, I remembered that I had a real-world, time-sensitive function that tested for odd and even numbers inside the main loop. It's an integer power function, posted elsewhere on StackOverflow, as follows. The benchmarks were quite surprising. At least in this real-world function, modulo is slower, and significantly so. The winner, by a wide margin, requiring 67% of modulo's time, is an or ( | ) approach, and is nowhere to be found elsewhere on this page.

static dbl  IntPow(dbl st0, int x)  {
    UINT OrMask = UINT_MAX -1;
    dbl  st1=1.0;
    if(0==x) return (dbl)1.0;

    while(1 != x)   {
        if (UINT_MAX == (x|OrMask)) {     //  if LSB is 1...    
        //if(x & 1) {
        //if(x % 2) {
            st1 *= st0;
        }    
        x = x >> 1;  // shift x right 1 bit...  
        st0 *= st0;
    }
    return st1 * st0;
}

For 300 million loops, the benchmark timings are as follows.

3.962 the | and mask approach

4.851 the & approach

5.850 the % approach

For people who think theory, or an assembly language listing, settles arguments like these, this should be a cautionary tale. There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.


Better to use unsigned x as x = x >> 1; is implementation-defined behavior when x < 0. Unclear why x and OrMask differ in type. Simple enough to re-write using a while(x) test.
I wonder which compiler you used to benchmark this, since most compilers should be smart enough to compile the % 2 case using the bitwise &. I just tested this and results are completely the same (VS2015, Release builds with all optimizations, both x86 and x64). The accepted answer also states this for GCC (written in 2008).
The problem with with this post is that the premise that a bitwise or would be any faster than an and is highly unlikely, on any platform/compiler. Even if there was such a weird platform/compiler combo (and you haven't posted neither that nor the code used to perform the benchmark), depending on other compilers to behave the same would be a poor optimization bet. So, as I wrote, I wonder which platform/compiler this was tested on, because I am almost certain it was not measured correctly.
Not calling you a liar, just claiming with high certainty that you didn't measure correctly. No need to call me a truck driver yet, read my original comment: I did make a benchmark, and results were, as expected, completely the same in all three cases (certainty of ~3 sigma, after running each test 10 times for 500.000.000 iterations). If you really have a long illustrious career, take a step back and think if your claims make sense, then post the actual code used to do the benchmark. Otherwise, the post is what I believe it is, just a mistake in measurement.
Done.
C
Community

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 believe you have committed the Cardinal Sin of benchmarking; creating one so specific it doesn't represent a real-world environment. Look at your assembly language and notice how few registers you are using. High marks for effort, but these results won't hold up in real-world processing.
@RocketRoy: since all outputs are exactly the same for all three cases (well, slightly worse for your program in one case), I don't really care how many registers were used. But again, feel free to create and post such example program/environment which will confuse the compiler to create a more optimized assembly in one of the cases, all other thing being equal.
I always like cocky programmers. It's a good trait for a programmer to have, but in a more complex, real-world program, my method will perform better than yours because the compiler has more ways to solve the problem so that instructions overlap (on Intel architectures) producing better results. Very few veteran programmers with good benchmarking experience would prefer your benchmark, but keep up the good work, and remember to rerun your benchmarks when new chip releases come out. Things do change over time.
r
rudigrobler

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

D
DocMax

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

W
Will Hartung

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.


p
plinth

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.


i
ilitirit

Portable:

i % 2 ? odd : even;

Unportable:

i & 1 ? odd : even;

i << (BITS_PER_INT - 1) ? odd : even;

佚名

As some people have posted, there are numerous ways to do this. According to this website, the fastest way is the modulus operator:

if (x % 2 == 0)
               total += 1; //even number
        else
               total -= 1; //odd number

However, here is some other code that was bench marked by the author which ran slower than the common modulus operation above:

if ((x & 1) == 0)
               total += 1; //even number
        else
               total -= 1; //odd number

System.Math.DivRem((long)x, (long)2, out outvalue);
        if ( outvalue == 0)
               total += 1; //even number
        else
               total -= 1; //odd number

if (((x / 2) * 2) == x)
               total += 1; //even number
        else
               total -= 1; //odd number

if (((x >> 1) << 1) == x)
               total += 1; //even number
        else
               total -= 1; //odd number

        while (index > 1)
               index -= 2;
        if (index == 0)
               total += 1; //even number
        else
               total -= 1; //odd number

tempstr = x.ToString();
        index = tempstr.Length - 1;
        //this assumes base 10
        if (tempstr[index] == '0' || tempstr[index] == '2' || tempstr[index] == '4' || tempstr[index] == '6' || tempstr[index] == '8')
               total += 1; //even number
        else
               total -= 1; //odd number

How many people even knew of the Math.System.DivRem method or why would they use it??


N
None
int isOdd(int i){
  return(i % 2);
}

done.


Your joke gives the wrong answer.
A
Astridax

To give more elaboration on the bitwise operator method for those of us who didn't do much boolean algebra during our studies, here is an explanation. Probably not of much use to the OP, but I felt like making it clear why NUMBER & 1 works.

Please note like as someone answered above, the way negative numbers are represented can stop this method working. In fact it can even break the modulo operator method too since each language can differ in how it deals with negative operands.

However if you know that NUMBER will always be positive, this works well.

As Tooony above made the point that only the last digit in binary (and denary) is important.

A boolean logic AND gate dictates that both inputs have to be a 1 (or high voltage) for 1 to be returned.

1 & 0 = 0.

0 & 1 = 0.

0 & 0 = 0.

1 & 1 = 1.

If you represent any number as binary (I have used an 8 bit representation here), odd numbers have 1 at the end, even numbers have 0.

For example:

1 = 00000001

2 = 00000010

3 = 00000011

4 = 00000100

If you take any number and use bitwise AND (& in java) it by 1 it will either return 00000001, = 1 meaning the number is odd. Or 00000000 = 0, meaning the number is even.

E.g

Is odd?

1 & 1 =

00000001 &

00000001 =

00000001 <— Odd

2 & 1 =

00000010 &

00000001 =

00000000 <— Even

54 & 1 =

00000001 &

00110110 =

00000000 <— Even

This is why this works:

if(number & 1){

   //Number is odd

} else {

   //Number is even
}

Sorry if this is redundant.


佚名

Number Zero parity | zero http://tinyurl.com/oexhr3k

Python code sequence.

# defining function for number parity check
def parity(number):
    """Parity check function"""
    # if number is 0 (zero) return 'Zero neither ODD nor EVEN',
    # otherwise number&1, checking last bit, if 0, then EVEN, 
    # if 1, then ODD.
    return (number == 0 and 'Zero neither ODD nor EVEN') \
            or (number&1 and 'ODD' or 'EVEN')

# cycle trough numbers from 0 to 13 
for number in range(0, 14):
    print "{0:>4} : {0:08b} : {1:}".format(number, parity(number))

Output:

   0 : 00000000 : Zero neither ODD nor EVEN
   1 : 00000001 : ODD
   2 : 00000010 : EVEN
   3 : 00000011 : ODD
   4 : 00000100 : EVEN
   5 : 00000101 : ODD
   6 : 00000110 : EVEN
   7 : 00000111 : ODD
   8 : 00001000 : EVEN
   9 : 00001001 : ODD
  10 : 00001010 : EVEN
  11 : 00001011 : ODD
  12 : 00001100 : EVEN
  13 : 00001101 : ODD

@el.pescado, Thank You. If Zero is even, how many pair it has?
@el.pescado, Ok, I'm agree with You. Then, If think a little bit, why we divide to 2 (two)? What we want to know, when we divide to two? Why not divide to 3, or, 5, etc.?
@el.pescado This Wikipedia article Parity of Zero is wrong. A lot of people has been fooled by this article. Think before Wink.
You're right. Now that I've read other answers I found yours the most comprehensive:)
@el.pescado. Thank You. :) Now You're Zero's best friend. (hug)
O
Omar Faruk
I execute this code for ODD & EVEN:

#include <stdio.h>
int main()
{
    int number;
    printf("Enter an integer: ");
    scanf("%d", &number);

    if(number % 2 == 0)
        printf("%d is even.", number);
    else
        printf("%d is odd.", number);
}

T
Tooony

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
}

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: 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, ah, my humour hat fell off. It is formly back on now :D Sorry about that :)
V
Vihung

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


-1: If you want to be efficient, use either one. If you want it to be portable, use %. If you want it to be readable, use %. Hmmm, I see a pattern here.
@trinithis, there is no pattern and this solution much much better than yours.
P
Pankaj Prakash

Checking even or odd is a simple task.

We know that any number exactly divisible by 2 is even number else odd.

We just need to check divisibility of any number and for checking divisibility we use % operator

Checking even odd using if else

if(num%2 ==0)  
{
    printf("Even");
}
else
{
    printf("Odd");
}

C program to check even or odd using if else

Using Conditional/Ternary operator

(num%2 ==0) printf("Even") : printf("Odd");

C program to check even or odd using conditional operator.

Using Bitwise operator

if(num & 1)  
{
    printf("Odd");
}
else 
{
    printf("Even");
}

and where exactly is the ternary operator?
C
Community

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