-
January 21st, 2010, 05:23 AM
#1
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.
-
January 21st, 2010, 08:13 AM
#2
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
-
January 21st, 2010, 10:52 AM
#3
Re: Can these two lines of code be simplified?
Originally Posted by OITGUY
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 11:35 AM.
-
January 21st, 2010, 11:52 AM
#4
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.
-
January 21st, 2010, 01:40 PM
#5
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;
}
-
January 21st, 2010, 01:53 PM
#6
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
}
-
January 21st, 2010, 04:20 PM
#7
Re: Can these two lines of code be simplified?
Originally Posted by OITGUY
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:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
January 21st, 2010, 04:42 PM
#8
Re: Can these two lines of code be simplified?
Right, that code is not equal to the original.
-
January 24th, 2010, 11:26 PM
#9
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;
}
-
January 25th, 2010, 03:34 AM
#10
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 03: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.
-
January 28th, 2010, 11:10 PM
#11
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.
-
January 29th, 2010, 12:08 AM
#12
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 29th, 2010 at 12:10 AM.
Reason: Added a link to the Wikipedia article.
-
January 29th, 2010, 12:42 PM
#13
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.
-
January 29th, 2010, 12:44 PM
#14
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|