Can these two lines of code be simplified?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14

Thread: Can these two lines of code be simplified?

  1. #1
    Join Date
    Jan 2010
    Posts
    7

    Question Can these two lines of code be simplified?

    PORTB ^= ~( 1 << pos );
    PORTB = ~PORTB;

    Just looking for to learn if there are any tricks to making this type of thing more concise. Thank you.

  2. #2
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Can these two lines of code be simplified?

    Well, comments are always nice :P

    Code:
    PORTB ^= ~(1 << pos);  //PORTB XOR  the 2's compliment of 2 ^ pos
    PORTB = ~PORTB;  //2's compliment of PORTB


    If you want something more readable
    Code:
    #define TIMES_TWO_TO_THE_POWER_OF\
       <<
    #define BINARY_NEGATION(x)\
       ~(x)
    #define SELF_XOR(var, x)\
       var ~= x
    
    SELF_XOR(PORTB, BINARY_NEGATION(1 TIMES_TWO_TO_THE_POWER_OF pos);
    PORTB = BINARY_NEGATION(PORTB);
    I personally find the latter harder to understand, but I've been using the binary operators for quiet some time

  3. #3
    Join Date
    May 2009
    Posts
    2,413

    Re: Can these two lines of code be simplified?

    Quote Originally Posted by OITGUY View Post
    PORTB ^= ~( 1 << pos );
    PORTB = ~PORTB;

    Just looking for to learn if there are any tricks to making this type of thing more concise. Thank you.
    What about a one-liner,

    PORTB = ~(PORTB ^ ~( 1 << pos ));

    For the sake of easier manipulation, you have this equivalent expression

    A = ~(A ^ ~B);

    which you can manipulate into

    A = ~((A & B) | (~A & ~B));
    A = ~~(A ^ B);
    A = (A ^ B);

    So the expression can be reduced to

    PORTB = PORTB ^ (1 << pos);

    or

    PORTB ^= (1 << pos);

    Once you've come up with a Boolean (or bitwise Boolean) expression you can always manipulate it to a minimal form using the rules of Boolean algebra.
    Last edited by nuzzle; January 21st, 2010 at 10:35 AM.

  4. #4
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Can these two lines of code be simplified?

    Ohhh, you meant a boolean algebra simplification. My mistake, I thought you meant you were confused by the notation, the word concise threw me off.

  5. #5
    Join Date
    Jan 2010
    Posts
    7

    Cool Re: Can these two lines of code be simplified?

    Thanks Nuzzle for the obvious one-liner that illuded me & the boolean simplification. I have learned to comment my code next time as this is my first thread- thanks ninja9578.

    This code is used for clearing or setting an output for Atmel AVR microcontrollers if anyone is curious.

    The function on a tutorial reads (our one-liner replaces the entire if-else statement):


    int set_PORTB_bit(int position, int value)
    {
    // Sets or clears the bit in position 'position'
    // either high or low (1 or 0) to match 'value'.
    // Leaves all other bits in PORTB unchanged.

    if (value == 0)
    {
    PORTB &= ~(1 << position); // Set bit position low
    }
    else
    {
    PORTB |= (1 << position); // Set high, leave others alone
    }

    return 1;
    }

  6. #6
    Join Date
    Jan 2010
    Posts
    7

    Lightbulb Re: Can these two lines of code be simplified?

    Here is the same code as last reply except formatted (newbie here):

    Code:
    int set_PORTB_bit(int position, int value)
    {
      // Sets or clears the bit in position 'position' 
      // either high or low (1 or 0) to match 'value'.
      // Leaves all other bits in PORTB unchanged.
                    
      if (value == 0)
      {
        PORTB &= ~(1 << position);      // Set bit position low
      }
      else
      {
        PORTB |= (1 << position);       // Set high, leave others alone
      }
    
      return 1;
    }
    equal to:

    Code:
    int set_PORTB_bit(int position, int value)
    {
       PORTB ^= (1 << pos);             // Set binary digit at index of 'position' with 'value', leave others unaltered
    }

  7. #7
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,527

    Re: Can these two lines of code be simplified?

    Quote Originally Posted by OITGUY View Post
    Code:
    int set_PORTB_bit(int position, int value)
    {
       PORTB ^= (1 << pos);             // Set binary digit at index of 'position' with 'value', leave others unaltered
    }
    I don’t think you should end a thread with multiple typos
    In your final statement the name “pos” is undefined and the parameter “value” is not used.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinViewer - an integrated GDI objects viewer for Visual C++ Debugger, and more...

  8. #8
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Can these two lines of code be simplified?

    Right, that code is not equal to the original.

  9. #9
    Join Date
    Jan 2010
    Posts
    7

    Resolved Re: Can these two lines of code be simplified?

    CORRECTED CODE:

    Code:
    int set_PORTB_bit(int position, int value)
    {
       PORTB ^= (value << position);             // Set binary digit at index of 'position' with 'value', leave others unaltered
    
       return 1;
    }

  10. #10
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Can these two lines of code be simplified?

    It's still not equivalent. For value 0 it won't do anything (and not clear the bit). As value is an int, it can also have values different from 0 or 1 and while the original function interprets any value other than 0 as "set the bit", your function will modify bits other than the one at position.
    Last edited by treuss; January 25th, 2010 at 02:36 AM.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  11. #11
    Join Date
    Jan 2010
    Posts
    7

    Can the code be reduced to less lines?

    Thank you treuss.

    Original code seeking to simplify:

    Code:
    int set_PORTB_bit(int position, int value)
    {
      // Sets or clears the bit in position 'position' 
      // either high or low (1 or 0) to match 'value'.
      // Leaves all other bits in PORTB unchanged.
                    
      if (value == 0)
      {
        PORTB &= ~(1 << position);      // Set bit position low
      }
      else
      {
        PORTB |= (1 << position);       // Set high, leave others alone
      }
    
      return 1;
    }
    Backtracking and starting over I see very little that can be done to make this code more concise, the following is slightly revised:

    Code:
    int set_PORTB_bit(int position, int value)
    {
      // Sets or clears the bit in position 'position' 
      // either high or low (1 or 0) to match 'value'.
      // Leaves all other bits in PORTB unchanged.
                    
      if (value)
        PORTB |= (1 << position);       // Set high, leave others alone
      else
        PORTB &= ~(1 << position);      // Set bit position low
    
      return 1;
    }
    The challenge I suppose is eliminating the if-else statement. There may be clever equivalent code alternatives but not sure.

  12. #12
    Join Date
    Mar 2006
    Posts
    142

    Re: Can these two lines of code be simplified?

    Based on your last post, are you not so much concerned with a concise executable but rather with concise source code?

    If so, is this closer to what you are after?

    Code:
    int set_PORTB_bit(int position, int value)
    {
      // Sets or clears the bit in position 'position' 
      // either high or low (1 or 0) to match 'value'.
      // Leaves all other bits in PORTB unchanged.
    
      PORTB = value ? (PORTB | (1 << position)) : (PORTB & ~(1 << position));
                    
      return 1;
    }
    You may be interested in the related topic "Kolmogorov complexity". See <http://en.wikipedia.org/wiki/Kolmogorov_complexity>.
    Last edited by GeoRanger; January 28th, 2010 at 11:10 PM. Reason: Added a link to the Wikipedia article.

  13. #13
    Join Date
    Jan 2010
    Posts
    7

    Re: Can these two lines of code be simplified?

    Thanks GeoRanger, the conditional operator is a good way to compress it to a one-liner.

    As for the optimization, the generated .hex files are the same using Windows AVR Studio 4 with "-Os" optimization, and also using the free GCC compiler. Seeing as how this is for implementing in a microcontroller, further optimization is definitely a good thing. I believe programmable flash memory sizes start at 1 kB for TinyAVR.

  14. #14
    Join Date
    Jan 2010
    Posts
    7

    Cool Re: Can these two lines of code be simplified?

    Also to clarify I am interested in both condensing source code and optimization.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center