Since I didn't know how to do this, I thought some people might want to know.
First off, the code:
Code:
int some_var=5; /* the variable we will be extracting a bit from. */
int n=3; /* the position of the bit we want */
the_bit = (( some_var & (1 << (n-1) ) ) ? 1 : 0 );
That's it!
Yes folks, a left shift, some binary logic, and the ternary operator, all in one line! looks impressive, huh? (Does anyone know if the PIC supports the ternary operator? if not, it's simple to convert to an if-else, but this is so clean! )
Now, some explanation:
We'll start by talking about the << operator.
This shifts whatever is to it's left of to the left the number of places given by the expression on it's right. In the code above, it shifts 1 left by 2 (n-1 = 3-1 = 2) places, filling spaces on the end with zeroes. This gives us 00000001 => 00000100 (assuming an 8 bit int, didn't check how large an int on the PIC is, but it doesn't matter for the point of this demonstration) An expression like this is known as a
mask, and can be used with the & operator to test a single bit.
Now you see that we compare the mask (1 << (n-1) ) with the variable to be tested using the binary bitwise and operator (&). It checks each bit place in each string against each other. Any place where both digits are 1 evaluate to 1. All other places evaluate to zero.
So, what we are really looking at in the example is
(00000101 & 00000100)
Which will evaluate to
(00000100)
Now, we plug this value (4) back into our ternary expression.
Time for a quick lesson in ternary! The ternary operator ? looks at the expression that precedes it. If the expression is true, the expression following the operator is evaluated. If it is false, then it ignores code until it reaches a : . It then procedes to evaluate whatever follows the colon.
In our example, we get an expression that looks like
4 ? 1 : 0;
Four is non-zero, so it evaluates to true. This means that the statement evaluates to 1. So, in our example,
Code:
int some_var=5; /* the variable we will be extracting a bit from. */
int n=3; /* the position of the bit we want */
the_bit = (( some_var & (1 << (n-1) ) ) ? 1 : 0 );
printf("the_bit: %d", the_bit);
OUTPUT:
the_bit: 1
A slightly more generalized look at the whole ternary statement now:
the_bit = (( some_var & (1 << (n-1) ) ) ? 1 : 0 );
First we create a mask with a 1 in the place of the bit we want to find and zeroes elsewhere. The zeroes elsewhere mean that the & on those bits will always evaluate to zero. The real comparison, therefore, only takes place on one bit, somevar.bit[n]. If this bit is one, then the expression returns a non-zero value, which is true, which then returns one from the ternary. If this is false, then the whole thing works out to zero, or false, so the ternary evaluates to 0.
And there you have it folks, how to fetch bits in c.