weird C- comparison

Thread Starter

takao21203

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

Rich (BB code):
   unsigned char key_handler(unsigned char k)
   {
       if(k==0==!(io_0&0x01))return(++k);
       if(k==1== (io_0&0x01))return(++k);
       return(k);
   }
The original code was:
Rich (BB code):
unsigned char key_handler(unsigned char k)
   {
       if(k==0){if((io_0&0x01)==0){k++;return(k);}}
       if(k==1){if((io_0&0x01)==1){k++;return(k);}}
       return(k);
   }
What I don't understand is why I need to insert a negation.
Since in the first line,
Rich (BB code):
(io_0&0x01)==0
is true.
So I changed it to
Rich (BB code):
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.
 

ErnieM

Joined Apr 24, 2011
8,377
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:


Rich (BB code):
   unsigned char key_handler(unsigned char k)
   {
       return(k + (k==io_0));
   }
 

t06afre

Joined May 11, 2009
5,934
Looking at your problem and given that io_0 also is a char is not your problem just
Rich (BB code):
if(k==(io_0&0x01)){k++;return(k);}
return(k)
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Looking at your problem and given that io_0 also is a char is not your problem just
Rich (BB code):
if(k==(io_0&0x01)){k++;return(k);}
return(k)
Yes this actually works. I was looking for something like that.

Rich (BB code):
if(k==(io_0&0x01))return(++k);
      return(k);
About 10 words are saved.
 

WBahn

Joined Mar 31, 2012
30,062
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));
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
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));
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.
 
Top