weird C- comparison

Discussion in 'Programmer's Corner' started by takao21203, Nov 5, 2012.

  1. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    Can someone explain? I changed C source code for a key handler.

    Code ( (Unknown Language)):
    1.    unsigned char key_handler(unsigned char k)
    2.    {
    3.        if(k==0==!(io_0&0x01))return(++k);
    4.        if(k==1== (io_0&0x01))return(++k);
    5.        return(k);
    6.    }
    The original code was:
    Code ( (Unknown Language)):
    1. unsigned char key_handler(unsigned char k)
    2.    {
    3.        if(k==0){if((io_0&0x01)==0){k++;return(k);}}
    4.        if(k==1){if((io_0&0x01)==1){k++;return(k);}}
    5.        return(k);
    6.    }
    What I don't understand is why I need to insert a negation.
    Since in the first line,
    Code ( (Unknown Language)):
    1. (io_0&0x01)==0
    is true.
    So I changed it to
    Code ( (Unknown Language)):
    1. k==0==(io_0&0x01)
    .
    But that did not work. The code worked like the key is continuously pressed and released.

    When I inserted the negation, it works like before, I have to press the key, and then release it.

    Also after the modification, 30 more program words are used. I hoped to save a few but the opposite is true.
     
  2. panic mode

    Senior Member

    Oct 10, 2011
    1,320
    304
    == equal
    != not equal
    <= smaller or equal
    >= greater or equal
    etc.
     
  3. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    Isn't about the question in the above post.
    == is used if you take a look.
     
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    You want us to explain why your code works in some fashion? Is not that a code maintance problem?

    Your code depends on the order of comparisons and that would requi research to determine if they group left to right or right to left by standard or by happenstance.

    You need the negation because:

    A==B==C. Becomes

    1 == C. So when C is zero you need to invert it.

    Or just try the following:


    Code ( (Unknown Language)):
    1.    unsigned char key_handler(unsigned char k)
    2.    {
    3.        return(k + (k==io_0));
    4.    }
     
  5. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    OK I understand it now.

    However the code that you wrote does not work.
     
  6. panic mode

    Senior Member

    Oct 10, 2011
    1,320
    304
    no, you started topic, your code does not work. rewrite conditions into conventional form and your problem will go away.
     
    ErnieM likes this.
  7. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Looking at your problem and given that io_0 also is a char is not your problem just
    Code ( (Unknown Language)):
    1. if(k==(io_0&0x01)){k++;return(k);}
    2. return(k)
    3.  
     
    takao21203 likes this.
  8. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    Someone started the thread, quite obvious.
    Actually my code does work.
     
  9. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    Yes this actually works. I was looking for something like that.

    Code ( (Unknown Language)):
    1. if(k==(io_0&0x01))return(++k);
    2.       return(k);
    About 10 words are saved.
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    I wonder if this is even smaller:

    Code ( (Unknown Language)):
    1. if(k==(io_0&0x01)) ++k;
    2. return(k);
     
  11. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    yes, this code works.
     
  12. WBahn

    Moderator

    Mar 31, 2012
    17,732
    4,789
    ErnieM's original suggestion would have worked except that it didn't take into account that other bits in io_0 might be set. Try the following:

    return k + (k==(io_0&0x01));

    Where is io_0 defined? Is it a global? What type is it?

    Is k a counter or just a flag. By checkiing for equality between k and a bit in another variable, you are treating it like it's a flag value. But by incrementing it, you are treating it like a counter.

    For instance, if k=1 and the lsb in io_0 is LO, you make set k=2.

    But if k is a counter, then presumably k could come in as some value other than 0 or 1, right? If so, then it doesn't matter what io_0 is, you will always just return k. Is that the behavior you want?

    Assuming it is, then if io_0 is also an unsigned char, then you might get some additional savings by avoiding the equality comparison altogether.

    return k + (0x01 & ~(k^io_0));
     
  13. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    3,577
    463
    1300 words remaining.

    return k + (k==(io_0&0x01));

    1292 words remaining. Works.

    return k + (0x01 & ~(k^io_0));

    1304 words remaining. Works.


    io_0 contains the bit from the I/O port. It is an unsigned char.
    k is only modified by the key handler.
    It is then tested for k==2. This means a key was pressed, and released.

    The relevant code is executed, and k is reset to 0.
     
Loading...