Reputation: 45
I came across some sample code which works perfectly for my application, but I am not sure what is actually going on in the IF statement.
unsigned int steps;
uint16_t selected_steps;
for (int j = 16; j>=0; j--)
{
if (((selected_steps^(1 << step_number))>>j) & 0x1) {
some code...
} else {
other code...
}
I know the purpose of the code, it is to check if the bit at selected_steps[j] XOR step_number is 1 or 0. Selected_steps[j] is either 0 or 1. Step number takes values between 0-15.
But I don't understand what is actually done by doing
(1 << step_number)
and then what is done by doing
selected_steps^(1 << step_number)) >> j
I suppose that the above statement outputs a 1 or 0 since it checks against 0x1?
Upvotes: 0
Views: 80
Reputation: 93476
Break it down into steps.
uint16_t mask = 1 << step_number ; // A bit mask with single
// bit `step_number` set.
uint16_t xor_step = selected_steps ^ mask ; // Toggle bit `step_number`.
uint16_t bit_j = (xor_step >> j) & 0x1 ; // Get the single bit `j`
if( bit_j ) ... // If bit j is not zero.
So for example when:
selected_steps == 0x5AA5 (binary:0101101010100101)
j == 5
step_number == 10
then:
mask = 1 << 10 (Binary: 0000001000000000)
selected_steps: 0101101010100101
mask: 0000001000000000
-----------------------
XOR: 0101100010100101 == xor_step
^
|_ Toggled bit
,- Bit 5 (j)
V
xor_step: 0101100010100101
shift right 5: >>>>>01011000101
^
|_ Bit 5 moved to LSB
0000001011000101
AND 1: 0000000000000001 == bit j
So you end up with bit j
of selected_steps
after bit step_number
has been toggled. If j != step_number
then the toggling has no effect on the result.
How that achieves the purpose of your application is not possible to tell given the aggressive eliding of your code. Presumably in reality selected_steps
and step_number
are not loop-invariant (and steps
not unused, and selected_steps
actually initialised for that matter)?
Upvotes: 1
Reputation: 222486
Consider what happens if step_number
differs from j
. Then: ((selected_steps^(1 << step_number))>>j) & 0x1
does this:
1 << step_number
changes some bit of selected_steps
other than bit j
. But, as we will see, we do not care about this.>>j
moves bit j
to position 0.& 0x1
isolates that bit.j
in selected_steps
is true.On the other hand, if step_number
equals j
, then the XOR changes bit j
, and the result is true iff bit j
in selected_steps
is false.
So the expression is equivalent to (step_number == j) != (selected_steps >> j & 1)
.
Upvotes: 4