Doubling bit shift in C

3

My question is regarding the following snippet of code:

    #include <stdio.h>

    int main(void){

    int teste = 0, x0 = 0, x1 = 0, x2;

    x2 = 1;
    teste = ((x0|x2) | (x1|x2) << 1);

    printf("Valor de teste: %d   ", teste);

    }

When I compile this code the value displayed for the test variable is 3 , however I do not understand what the following excerpt does, teste = ((x0|x2) | (x1|x2) << 1); Could you help me?

    
asked by anonymous 29.04.2017 / 01:44

2 answers

2

When so, separate each operation to see each step occurring, as you would on paper.

#include <stdio.h>

int main(void) {
    int x0 = 0, x1 = 0, x2 = 1;
    printf("Valor de x0 | x2: %d\n", x0 | x2);
    printf("Valor de x1 | x2: %d\n", x1 | x2);
    printf("Valor de (x1 | x2) << 1: %d\n", (x1 | x2) << 1);
    printf("Valor de (x0 | x2) | (x1 | x2) << 1: %d\n", (x0 | x2) | (x1 | x2) << 1);
}

See running on ideone . And No Coding Ground . Also put it on GitHub for future reference .

By the truth table an OR operator results in 1 whenever at least one of the operands is 1. This is the case of the two subexpressions that use the or operator ( | ).

It turns out that by operator precedence table << is executed earlier. This is the bit shift operator (see the links below). Then you are sending a bit to the left. The number 1 in binary is 00000001 . Moving a bit would be 00000010 . And this decimal number is 2.

Finally the last calculation will be done, which is again an OU. Then there will be a comparison between 00000001 and 00000010 , the results of the two expressions on each side. Then the result will always be 1 when one of it is 1. Therefore it will result in 00000011 because it has 1 in the last bit in one operand and has 1 in the penultimate bit of the second operand. The% w / o% in decimal is 3, the end result.

Examples and additional information:

29.04.2017 / 02:06
3

This section works with the number binary, you should understand how each works:

1) The symbol "|" means "inclusive OR" and what it does is the following:

Make the bit value equal to 1 if one or both of the corresponding bits in the operands is 1 and 0 in all other cases. Example: if the var variable has the value 12 (00001100) and doing the operation with 6 (00000110), the result, var | 6, it will be 14 (00001110).

2) The symbol "< <" means "left shift" and what it does is the following:

Shift left bits of the left operand to the value given by the right operand. Equivalent to the multiplication by the power of 2 given by the latter. Example: If the var variable has the value 3 (00000011), after var < 2, it will be 12 (00001100).

So what your code is doing is more or less this:

teste = ((x0|x2) | (x1|x2) << 1);
teste = ((00000000|00000001) | (00000000|00000001) << 00000001);
teste = (00000001 | 00000001 << 00000001);
//O operador << tem precedência, então neste momento ele é executado primeiro
teste = (00000001 | 00000001 << 00000001);
teste = (00000001 | 00000010);
teste = (00000011);
teste = (3);

If you still have doubts about any other type of operator, this page link explains well the operation of each one.

    
29.04.2017 / 02:06