• cyborg (unregistered) in reply to no laughing matter
    no laughing matter:
    Jim the Tool:
    no laughing matter:
    If your compiler isn't able to optimise i % 2 to i & 1 than your compiler is TRWTF.
    Hey my son is a compiler that isn't able to optimise i % 2 to i & 1, and let me tell you, it's no laughing matter!
    Would have worked better if you had learned the correct button is always the quote button! (i simulated that for you, daddy!)

    That's one for the fridge door.

  • allbillernofiller (unregistered) in reply to mpoly

    Close, but breaks for even numbers from 10-18, calling them odd.

  • allbillernofiller (unregistered) in reply to mpoly
    mpoly:
    use Lingua::EN::Numbers qw(num2en); sub isodd {return (num2en shift) =~ /e.?$/}

    Close, but breaks for even numbers from 10-18, calling them odd.

    Guess I meant to hit "quote". WTF can't comment right.

  • Evan (unregistered) in reply to GWO
    GWO:
    You don't need a double cast...

    bool isOdd(int n) { return n >= 0 ? (n/2 == (n-1)/2) : isOdd(-n); }

    Which, unlike the (n & 0x1) or the (n % 2) solution, actually guarantees[0] the correct answer for n < 0. C is not a two-complement language, even though it kinda is.

    [0] Well, nearly. isOdd(INT_MIN) will recurse infinitely. Yay, C.

    n%2 guarantees the correct solution as long as you say if(n % 2), if(n % 2 != 0), or something similar or opposite instead of if(n % 2 == 1).

  • gnasher729 (unregistered) in reply to Oddie
    Oddie:
    Also doesn't work for negative numbers.
    It does in many languages (if the bigger bug is fixed first), just takes very, very long. And don't use 64 bit integers, please.
  • Evan (unregistered) in reply to allbillernofiller
    allbillernofiller:
    Guess I meant to hit "quote". WTF can't comment right.
    I'd say that TRWTF is forum software where the obvious choice to reply to someone is next to useless, but I'm worried that Alex will just use that as an excuse to push out discourse sooner. So I love the reply button! It's great!
  • gnasher729 (unregistered) in reply to gallier2
    gallier2:
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    and the experienced one gets a kick in the nuts for providing the heaviest and the slowest solution.

    The 2 obvious solution get compiled in 1 and assembly instruction, the other one needs the load of an address (4 byte immediate or 8 byte immediate on a 64 bit machine) and a load base+index instruction, which has the side effect of loading the lookup_table into the cache which might evict more precious data. It annoys me always when algorithm are compared in a imaginary machine that knows nothing about registers, caches (lvl 1, 2 or 3), local memory, remote memory (on multi socket machines) etc.

    I'd say #1 and #3 should be kicked for giving an incorrect solution to a trivial problem (both fail for x < 0, the second fails for x >= 10).

  • deleted (unregistered) in reply to gnasher729
    gnasher729:
    gallier2:
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    and the experienced one gets a kick in the nuts for providing the heaviest and the slowest solution.

    The 2 obvious solution get compiled in 1 and assembly instruction, the other one needs the load of an address (4 byte immediate or 8 byte immediate on a 64 bit machine) and a load base+index instruction, which has the side effect of loading the lookup_table into the cache which might evict more precious data. It annoys me always when algorithm are compared in a imaginary machine that knows nothing about registers, caches (lvl 1, 2 or 3), local memory, remote memory (on multi socket machines) etc.

    I'd say #1 and #3 should be kicked for giving an incorrect solution to a trivial problem (both fail for x < 0, the second fails for x >= 10).

    I'd say the previous commenter should be kicked for failing to read the original requirement, which placed a strict limit on the input values.

  • n_slash_a (unregistered) in reply to Pock Suppet
    Pock Suppet:
    Obviously you're all wrong. It should be
    bool function isOdd(int x) {
      return (x = 0) ? false : !isOdd(abs(x)-1)
    }
    because there's not a problem that can't be solved with recursion! It's the functional way!
    This should be the Feature Comment!
  • foo AKA fooo (unregistered) in reply to deleted
    deleted:
    gnasher729:
    gallier2:
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    and the experienced one gets a kick in the nuts for providing the heaviest and the slowest solution.

    The 2 obvious solution get compiled in 1 and assembly instruction, the other one needs the load of an address (4 byte immediate or 8 byte immediate on a 64 bit machine) and a load base+index instruction, which has the side effect of loading the lookup_table into the cache which might evict more precious data. It annoys me always when algorithm are compared in a imaginary machine that knows nothing about registers, caches (lvl 1, 2 or 3), local memory, remote memory (on multi socket machines) etc.

    I'd say #1 and #3 should be kicked for giving an incorrect solution to a trivial problem (both fail for x < 0, the second fails for x >= 10).

    I'd say the previous commenter should be kicked for failing to read the original requirement, which placed a strict limit on the input values.

    And for confusing >= with >.

  • (cs)

    I'm not sure if TRWTF is the number of people who don't see that Steve the Cynic is passing in an unsigned int, or if it's how many more comments we get without Discourse.

  • (cs) in reply to SuomynonA
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    None of the functions checks the parameter for range. In the first two, the function will still work. In the version by the "most experienced" programmer, if a bad parameter is passed, there will be a subscript out of range error and garbage will be returned.

    Sincerely,

    Gene Wirchenko

  • Zapp Brannigan (unregistered)

    We have an Oracle table with two columns, col1_number_id and col2_odd_even with a row for each integer between 0 and 4294967296. Then I just run a simple select SQL to determine if a number is odd or even. Couldn't be simpler. Loading the table took a while since I had to enter each row by hand.

  • Valued Service (unregistered) in reply to Steve The Cynic
    Steve The Cynic:
    This is not the worst way I ever heard of to determine if a number is odd or even.

    That prize is awarded to a jolly chap whose meanderings during an interview were described to me by the interviewer.

    bool isOdd( unsigned number )
    {
      unsigned counter = 0;
    
      while( 1 )
      {
        if( counter == number )
          return false;
    
        counter++;
    
        if( counter == number )
          return true;
      }
    }

    Great, O(n) to find if n is odd... (Depending on the divide support in the CPU, the conventional method might be as heavy as O(log2(n)).)

    Some people fail at math.

    I had a statistics professor in college.

    He drew a picture on the board of a set of circles, arranged in a two by three grid.

    He asked a student to count the circles.

    The student starting counting. 1, 2, 3...

    The professor told him he failed at counting, then announced the answer was 2x3 = 6.

    Then he said, now I'm going to teach you how to count probability.

  • deleted (unregistered) in reply to Gene Wirchenko
    Gene Wirchenko:
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    None of the functions checks the parameter for range. In the first two, the function will still work. In the version by the "most experienced" programmer, if a bad parameter is passed, there will be a subscript out of range error and garbage will be returned.

    Sincerely,

    Gene Wirchenko

    There was no requirement to check for range. It was specifically stated that the input was limited to 0>n>10 (or >= if you assume 'inclusive'. That means that the function is relieved of the requirement to consider values of n outside of this limit. ... Defensive programming would suggest a limits check anyway, but the stated requirements do not. ... I hope Gene Wirchenko doesn't translate requirements into code for a living.

    Captcha: gravis -> It is a gravis error to confuse your understanding of requirements, with what they actually say.

  • (cs) in reply to Modulo
    Modulo:
    Seriously, the modulo operator is overrated, isn't it? ;-)
    Yes, it is. Fortran doesn't have one, so it isn't necessary. Of course, there are other ways to get the answer (left as an exercist for the reader).

    Addendum (2014-07-22 15:36): s/exercist/exercise/

  • (cs)
    char foo[100];
    int i;
    sprintf(foo, "%d", n);
    i = strlen(foo);
    if (foo == '1' || foo[i] == '3' || foo[i] == '5' || foo[i] == '7' || foo[i] == '9')
        /* 0 is frist, so odd */
        return even;
    else
        return odd;
    

    Haven't used C in some years so please ignore any syntax errors.

    [i]Addendum (2014-07-22 15:37): i = strlen(foo)-1;

    and first "foo" comparison should be "foo[i]". Sheesh.

  • Joris (unregistered)

    That's weird, Visual Basic's Str() always uses '.' as decimal separator. Perhaps he used CStr() which is indeed culture specific?

    Source: http://msdn.microsoft.com/en-us/library/4y6a1sx7(v=vs.90).aspx

  • (cs) in reply to herby
    herby:
    Modulo:
    Seriously, the modulo operator is overrated, isn't it? ;-)
    Yes, it is. Fortran doesn't have one, so it isn't necessary. Of course, there are other ways to get the answer (left as an exercist for the reader).

    Addendum (2014-07-22 15:36): s/exercist/exercise/

    Yes it does -- we used to use YR2 = MOD(YR, 100) all the time to get a 2-digit year from a 4-digit year.

  • Brian (unregistered)

    And while VB is available only on two's complement binary machines, C89 does not insist on two's complement, or even binary. BZZZT on all the bit twiddlers,

    return number % 2;
    is the only reasonable maximally conformant solution suggested yet.

  • Friedrice The Great (unregistered) in reply to herby
    herby:
    Modulo:
    Seriously, the modulo operator is overrated, isn't it? ;-)
    Yes, it is. Fortran doesn't have one, so it isn't necessary. Of course, there are other ways to get the answer (left as an exercist for the reader).

    Addendum (2014-07-22 15:36): s/exercist/exercise/

    "sexercist exercise"? Is this some new sex therapy professional treatment? Does it involve demonic possession?

    No, inquiring minds DON'T want to know.

    And WTF is getting political? Captcha: abbas

  • Norman Diamond (unregistered) in reply to cyborg
    cyborg:
    Steve The Cynic:
    Great, O(n) to find if n is odd... (Depending on the divide support in the CPU, the conventional method might be as heavy as O(log2(n)).)
    Hell no, for ints all you do is check the least significant bit and you're done! It's a constant time check - it really couldn't be easier. Having said that I have no idea if (x % 2 == 0) would be compiled to that if that is the mechanism you refer to.
    When talking about ints rather than unsigned ints, you have to consider all the ways that C allows negative values to be represented. Checking the least significant bit doesn't solve it. if (x % 2 == 0) does. You're right not to have any idea of whether your correct solution would be compiled to your WTF; it depends on the machine.
  • Norman Diamond (unregistered) in reply to Miriam
    Miriam:
    bool isOdd(int n){
       return n / 2 < ((double) n) / 2;
    }
    
    Do I get a 🍪 now?
    No, I gave you your ; but you don't get a 🍪.

    You too, with n being int instead of unsigned int, should check what you return for isOdd(-3). For most versions of C the answer depended on the machine. For most machines and I think now for all machines you'd be guaranteed to return the wrong answer.

  • sdfg (unregistered) in reply to GWO
    GWO:
    You don't need a double cast...

    bool isOdd(int n) { return n >= 0 ? (n/2 == (n-1)/2) : isOdd(-n); }

    Which, unlike the (n & 0x1) or the (n % 2) solution, actually guarantees[0] the correct answer for n < 0. C is not a two-complement language, even though it kinda is.

    [0] Well, nearly. isOdd(INT_MIN) will recurse infinitely. Yay, C.

    why does the bit test fail for odds?

  • Jim (unregistered) in reply to Valued Service
    Valued Service:
    Steve The Cynic:
    This is not the worst way I ever heard of to determine if a number is odd or even.

    That prize is awarded to a jolly chap whose meanderings during an interview were described to me by the interviewer.

    bool isOdd( unsigned number )
    {
      unsigned counter = 0;
    
      while( 1 )
      {
        if( counter == number )
          return false;
    
        counter++;
    
        if( counter == number )
          return true;
      }
    }

    Great, O(n) to find if n is odd... (Depending on the divide support in the CPU, the conventional method might be as heavy as O(log2(n)).)

    Some people fail at math.

    I had a statistics professor in college.

    He drew a picture on the board of a set of circles, arranged in a two by three grid.

    He asked a student to count the circles.

    The student starting counting. 1, 2, 3...

    The professor told him he failed at counting, then announced the answer was 2x3 = 6.

    Then he said, now I'm going to teach you how to count probability.

    I don't get it

  • Evan (unregistered) in reply to sdfg
    sdfg:
    GWO:
    You don't need a double cast...

    bool isOdd(int n) { return n >= 0 ? (n/2 == (n-1)/2) : isOdd(-n); }

    Which, unlike the (n & 0x1) or the (n % 2) solution, actually guarantees[0] the correct answer for n < 0. C is not a two-complement language, even though it kinda is.

    [0] Well, nearly. isOdd(INT_MIN) will recurse infinitely. Yay, C.

    why does the bit test fail for odds?
    Because C doesn't guarantee 2's complement. Even C99 allows 2's complement, 1's complement, and sign+magnitude (x&1 works, doesn't work, works respectively); C89 I think allows pretty arbitrarily-crazy representations. I don't know about C++11, but C++98/03 probably matches C89.

  • asifyoucare (unregistered) in reply to Miriam
    Miriam:
    bool isOdd(int n){
       return n / 2 < ((double) n) / 2;
    }
    
    Do I get a 🍪 now? I hate the fact that I always want to write in C-like Syntax even though I currently work with VB.NET at work. ARRRGH SEMICOLONS

    Not sure if serious. No need for any calculations based on iBoucle.

    isOdd = 1; for (iBoucle = 0; iBoucle < Whatever ; iBoucle++) { isOdd = ! isOdd; if (isOdd) { .... } }

  • GWO (unregistered) in reply to sdfg
    sdfg:
    GWO:
    You don't need a double cast...

    bool isOdd(int n) { return n >= 0 ? (n/2 == (n-1)/2) : isOdd(-n); }

    Which, unlike the (n & 0x1) or the (n % 2) solution, actually guarantees[0] the correct answer for n < 0. C is not a two-complement language, even though it kinda is.

    [0] Well, nearly. isOdd(INT_MIN) will recurse infinitely. Yay, C.

    why does the bit test fail for odds?
    Because C doesn't impose any restriction on how negative numbers are represented. If the compiler writer chose to use 32bit one's complement, then the representation of -1 would 0xFFFFFFFE, which has a zero as the least significant bit.

  • cyborg (unregistered)

    Ok, I see some people don't grasp that modulo maths ISN'T sign dependent. Hence it would be best to express what you want as % 2 which is always right regardless of sign or anything else because of what modulo arithmetic is. If the compiler realises that it can optimise this to & 1 then all the better.

    Go try determining the truth value of -1 % 2 != 1 % 2 in your favourite language otherwise if you disagree. I'll wait.

  • Brian (unregistered) in reply to cyborg

    Unfortunately, % is not a modulus operator, it is a remainder after division operator.

  • GWO (unregistered) in reply to cyborg
    cyborg:
    Ok, I see some people don't grasp that modulo maths ISN'T sign dependent. Hence it would be best to express what you want as % 2 which is always right regardless of sign or anything else because of what modulo arithmetic is.
    Except ... the C % operator does not do what you think it should do (at least not in C89/C90).

    Compilers are perfectly at liberty, to say that (-1 % 2) = -1 or (-1 % 2) = +1, as long as they specify which, and are consistent. So (x % n) is only guaranteed to be in [0,1...n-1] if x is positive.

    So, for a compiler that chooses that says (-7 % 2) = -1 then they're really not the same, unless you convert explicitly convert them to bool.

    C99 removes the ambiguity, and says x % n must have the same sign as n.

  • The Fury (unregistered) in reply to Gene Wirchenko
    Gene Wirchenko:
    SuomynonA:
    This reminds me of one old joke:

    Three C coders write a function that takes an integer argument between 0 and 10 and returns 1 if argument is odd, 0 if it is even.

    Newbie coder writes this:

    int isOdd(int x)
    {
      if (x % 2 == 1)
        return 1;
      else
        return 0;
    }

    Second, more experienced coder writes this:

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

    Third one, the most experienced of them, writes this:

    int isOdd(int x)
    {
      static const int lookup_table[] = {0,1,0,1,0,1,0,1,0,1,0};
      return lookup_table[x];
    }

    None of the functions checks the parameter for range. In the first two, the function will still work. In the version by the "most experienced" programmer, if a bad parameter is passed, there will be a subscript out of range error and garbage will be returned.

    Sincerely,

    Gene Wirchenko

    Not necesarily. Who knows what will happen if a bad parameter is passed. Address exception and process crash are just as likely. Which is fine, because the behaviour is undefined.

  • cyborg (unregistered) in reply to GWO
    GWO:

    ...

    C99 removes the ambiguity, and says x % n must have the same sign as n.

    Your education is appreciated sir - I was not aware of the previous state of affairs with regards to the treatment of that operator. Still for the odd/even thing 2 % 2 == -2 % 2 which is zero so anything !(x % 2) is going to be safe here.

  • (cs)

    Why is no_laughing_matter still alive?

  • (cs) in reply to Nagesh
    Nagesh:
    Why is no_laughing_matter still alive?
    Why is false Nagesh adding underscores to my name instead of performing compulsory coding labor?
  • Evan (unregistered) in reply to GWO
    GWO:
    Compilers are perfectly at liberty, to say that (-1 % 2) = -1 or (-1 % 2) = +1, as long as they specify which, and are consistent.
    And are consistent with /.

    So you can have -1 % 2 = -1 iff -1 / 2 == 0, or you can have -1 % 2 = 1 iff -1 / 2 = -1. Either way is consistent with C89 and C++98/03.

    cyborg:
    Still for the odd/even thing 2 % 2 == -2 % 2 which is zero so anything !(x % 2) is going to be safe here.
    Provided that you compare against zero and not one, as some people have in this thread. if (x % 2 == 0) { /* even */ } is OK; if (x % 2 == 1) { /* odd */ } is not.

    (And of course omitting the explicit comparison from the conditional is fine, because that's comparing against zero.

  • (cs) in reply to deleted
    deleted:
    Gene Wirchenko:
    None of the functions checks the parameter for range. In the first two, the function will still work. In the version by the "most experienced" programmer, if a bad parameter is passed, there will be a subscript out of range error and garbage will be returned.

    There was no requirement to check for range. It was specifically stated that the input was limited to 0>n>10 (or >= if you assume 'inclusive'. That means that the function is relieved of the requirement to consider values of n outside of this limit.

    There was no requirement to quit thinking either.

    Defensive programming would suggest a limits check anyway, but the stated requirements do not.

    Exactly. Why the limits anyway?

    I hope Gene Wirchenko doesn't translate requirements into code for a living.

    It is part of my living. I would flag such a requirement and go for a function that has no limits, unless those limits are important, in which case, we are back to it being a good idea to limit check.

    Sincerely,

    Gene Wirchenko

  • SG_01 (unregistered) in reply to Pock Suppet
    Pock Suppet:
    Obviously you're all wrong. It should be
    bool function isOdd(int x) {
      return (x = 0) ? false : !isOdd(abs(x)-1)
    }
    because there's not a problem that can't be solved with recursion! It's the functional way!

    Sure, infinite recusion is fun :)

  • the real WTF (unregistered)

    Why is Str not determistic? Who wants a localized decimal point, should use an appropriate function, not Str

  • Norman Diamond (unregistered) in reply to SG_01
    SG_01:
    Pock Suppet:
    Obviously you're all wrong. It should be
    bool function isOdd(int x) {
      return (x = 0) ? false : !isOdd(abs(x)-1)
    }
    because there's not a problem that can't be solved with recursion! It's the functional way!
    Sure, infinite recusion is fun :)
    Pock Suppet has better abs than SG_01.
  • Neil (unregistered) in reply to GWO
    GWO:
    C99 removes the ambiguity, and says x % n must have the same sign as n.
    Sorry, but it's the same sign as x, not n.
  • JJ (unregistered) in reply to nmclean
    nmclean:
    abarker:
    An Odd Way to Find Even Numbers:
    Fred S. never much cared for zebra striping, the UI pattern than was all the rage after Mac OS X launched in 2001.

    Nice try, but no. "zebra striping" existed well before 2001. It actually started on gasp stationary which is commonly referred to as "greenbar continuous stationary", "greenbar continuous feed", or just "greenbar".

    As for why Fred never cared for it, to each their own. Many people find it a simple, clear way of delineating between rows so that you can follow them across the table somewhat more easily than if you just rely on borders.

    To be fair, there is a difference between "be all the rage" and "exist".
    Not to mention the difference between "stationary" and "stationery."

  • d (unregistered) in reply to faoileag

    Using nth-child is far less performant than adding a class, especially if it is the right most selector.

  • Paul (unregistered)

    Here's a slightly more subtle (broken) Java odd/even example (from real code):

    public boolean isEven(int n) {
        return n % 2 == 0;
    }
    
    public boolean isOdd(int n) {
        return n % 2 == 1;
    }
    

    Hint: it's isOdd() that is broken. :-)

  • Paul (unregistered) in reply to Paul

    Oh, as already noted by others above. ;-)

Leave a comment on “An Odd Way to Find Even Numbers”

Log In or post as a guest

Replying to comment #:

« Return to Article