S
Bit-to-bit operations, bit-to-bit operations or binary logic usually refers to logical operations made with binary numbers. These operations range from operations AND, OR, NOT, XOR, NOR, NAND, https://pt.stackoverflow.com/questions/10174/como-funciona-o-deslocamento-de-bits-em-c-c , among other operations. It should be said that some of these operations here are groupings of other operations, such as NAND, which is a grouping of a logic AND with logic NOT. There are also interesting things to be studied, such as Boole algebra (or http://pt.wikipedia.org/wiki/%C3%81lgebra_booliana ) and http://pt.wikipedia.org/wiki/Teoremas_de_De_Morgan . Operation NOT.The operation NOT (NO), also called "negation" or "inversion", is the simplest of operations, as it consists in inverting the state of bits. Take as an example the binary number 00111100. After passing an operation NOT becomes 11000011. In some programming languages, such as C, if you use the operator ~ to reverse the state of bits. The operation NOT follows the truth table:Take as an example the following code in C:unsigned char x, y;
x = 44;
printf("x = %d\n", x);
y = ~x;
printf("~x = %d\n", y);
This passage results in the following impression:x = 44
~x = 211
You can check the size a variable occupies in C through function call sizeof(type). This function returns the size of the variable in bytes, so that it is necessary to multiply the result by 8 to get the value in bits.printf("Tamanho do char é de %d bits e %d byte (s)\n", (sizeof(char) * 8), sizeof(char));
This passage results in the following impression:Tamanho do char é de 8 bits e 1 byte (s)
By the fact of the guy char in C be an 8-bit variable, while attributing x = 44 what you are doing is assigning a variable that contains the value 00101100. Or better:x = 44 é:
128| 64| 32| 16| 8| 4| 2| 1
0| 0| 1 | 0 | 1| 1| 0| 0
Therefore, we have 32 + 8 + 4 that is equivalent to the 44 already mentioned. But when the operation goes on NOT, you reverse the state of these bits, getting:x = 44 é:
0| 0| 1| 0| 1| 1| 0| 0
y = ~x é:
1| 1| 0| 1| 0| 0| 1| 1 Equivalente a 211
One thing that is interesting to note is that the reverse of 44 in an 8-bit variable is 211. An 8-bit variable stores 256 values, with these values from 0 to 255, then it can be said that by denial, you get the remaining value at 255 (44 + 211 = 255).Operation AND.The operation AND (E), also called "conjunction", has as symbol the * or . and returns 1 when, and only when, all bits are 1 (or true). In language C this operation has as symbol the & between two variables. The operation AND (OU) is an operation that follows the following truth table:Let us now take the following passage of code:y = x & 67;
printf("x & 67 = %d\n", y);
This passage results in the following impression:x & 67 = 0
x still equals 44, i.e. 00101100 in binary. When performing an operation AND with 67 (01000011 in binary) what is actually doing is:MSB (Most Significant Bit)
x & 67
0 AND 0 => 0
0 AND 1 => 0
1 AND 0 => 0
0 AND 0 => 0
1 AND 0 => 0
1 AND 0 => 0
0 AND 1 => 0
0 AND 1 => 0
LSB (Least Significant Bit)
00000000 binário => 0 decimal
Therefore, an operation AND between 44 & 67 returns the number 0, printed on the following line.Operation OR.The operation OR (OU), also called "disjunction", has as symbol the +. This operation returns 1 when any of the bits is 1 and returns 0 when ALL bits are 0. The operation OR is an operation that follows the following truth table:In the language C, the operator is used | to perform an OR operation between two variables. As in the following code:y = x | 129;
printf("x | 129 = %d\n", y);
This passage results in the following impression:x | 129 = 173
x that's worth 44, i.e. 00101100 in binary, is in a disjuring operation with 129 (10000001 in binary). When performing an operation OR between 44 and 129 what is actually doing is:MSB (Most Significant Bit)
x & 67
0 OR 1 => 1
0 OR 0 => 0
1 OR 0 => 1
0 OR 0 => 0
1 OR 0 => 1
1 OR 0 => 1
0 OR 0 => 0
0 OR 1 => 1
LSB (Least Significant Bit)
10101101 binário => 173 decimal
Therefore, an operation OR between 44 & 129 returns the number 173, printed on the next line.Operation XOR.The operation XOR (O Exclusive), also called "exclusive disjoint", is a logical operation between two operands that results in a true logical value if, and only if, exactly one of the operands has true value. It can be synthesized as a difference detector between two logical operands. This operation follows the following truth table:The XOR operation is an interesting way to change the value of two variables without needing a third, as demonstrated by the excellent response given by Lucas Nunes https://pt.stackoverflow.com/questions/9497/como-funciona-o-algoritmo-do-xor-swap .In the language C, the operator is used ^ to perform an operation XOR between two variables. As in the following code:y = x ^167;
printf("x ^167 = %d\n", y);
Which results in printing: x ^167 = 139
Yeah. 44 (00101100) XOR 167 (10100111):MSB (Most Significant Bit)
x ^ 167
0 XOR 1 => 1
0 XOR 0 => 0
1 XOR 1 => 0
0 XOR 0 => 0
1 XOR 0 => 1
1 XOR 1 => 0
0 XOR 1 => 1
0 XOR 1 => 1
LSB (Least Significant Bit)
10001011 binário => 139 decimal
Therefore, an operation XOR between 44 & 167 returns the number 139, printed on the next line.Displacement of bits.In language C use the operators >> or << to offset bits between variables to the right or left. The displacement of bits, as the name already says, is a technique of moving bits to one or more houses. An interesting feature of bit displacement is that it is possible to multiply or divide the value of that variable, but I will not enter details about this in this answer.The bit shift works as follows, for example, when moving a variable x to the left:int x = 1; // 0000 0001
int x0 = (x << 0); // 0000 0001 Não deslocado
int x1 = (x << 1); // 0000 0010
int x2 = (x << 2); // 0000 0100
int x3 = (x << 3); // 0000 1000
int x4 = (x << 4); // 0001 0000
int x5 = (x << 5); // 0010 0000
int x6 = (x << 6); // 0100 0000
int x7 = (x << 7); // 1000 0000
Now move to the right:int x = 128; // 1000 0000
int x0 = (x >> 0); // 1000 0000 Não deslocado
int x1 = (x >> 1); // 0100 0000
int x2 = (x >> 2); // 0010 0000
int x3 = (x >> 3); // 0001 0000
int x4 = (x >> 4); // 0000 1000
int x5 = (x >> 5); // 0000 0100
int x6 = (x >> 6); // 0000 0010
int x7 = (x >> 7); // 0000 0001
I'm not going to get much deeper into this technique, but I recommend reading Lucas Nunes' excellent response https://pt.stackoverflow.com/questions/10174/como-funciona-o-deslocamento-de-bits-em-c-c , from where I took the example above. But in the case of the code you provided in your question, what happens is:y = x << 2;
printf("x <<2 = %d\n", y);
The above code excerpts:x <<2 = 176
Yeah. 00101100 em binário é 44 em decimal
00101100 << 2
01011000 //Moveu 1 bit a esquerda
10110000 //Moveu 2 bits a esquerda
10110000 em binário => 176 decimal
y = x >> 2;
printf("x >>2 = %d\n", y);
The above code excerpts:x >>2 = 11
Yeah.00101100 em binário é 44 em decimal
00101100 >> 2
00010110 //Moveu 1 bit a direita
00001011 //Moveu 2 bits a direita
00001011 em binário => 11 decimal
Applications.Operations with bits are widely used when programming low level. You can configure https://pt.stackoverflow.com/questions/10174/como-funciona-o-deslocamento-de-bits-em-c-c and make code optimizations, for example. They are also used in https://pt.stackoverflow.com/questions/43492/como-funciona-o-algoritmo-de-criptografia-aes , because they are logical operations are less costly to the processor. In digital electronics, they are used at all times.