What are logical operators and how does bit-by-bit operations work in the C language?

What are logical operatorsNOT, AND, OR, XOR, in language C?

I also did not understand these operators: ~, &, |, ^, >>, << and the result in bits. I have the following code example:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   unsigned char x, y;
   x = 44;
   printf("x = %d\n", x);
   y = ~x;
   printf("~x = %d\n", y);
   y = x & 67;
   printf("x & 67 = %d\n", y);
   y = x | 129;
   printf("x | 129 = %d\n", y);
   y = x ^167;
   printf("x ^167 = %d\n", y);
   y = x <<2;
   printf("x <<2 = %d\n", y);
   y = x >>2;
   printf("x >>2 = %d\n", y);
   system("pause");
   return 0;
}
Author: Avelino, 2015-05-10

1 answers

Bitwise operations, bitwise operations or binary logic, usually refers to logical operations done with binary numbers. These operations range from operations AND, OR, NOT, XOR, NOR, NAND, simple bit shift , among other operations. It should be said that some of these operations mentioned 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 Boolean algebra ) and De Morgan's theorems.

Operation NOT.

Operation NOT (No), also called "negation" or "inversion", is the simplest of operations, as it consists of reversing the state of the bits. Take as an example the binary number 00111100. After going through an operation NOT becomes 11000011. In some programming languages, such as C, you use the ~ operator to reverse the bit State. The operation NOT follows the truth table:

insert the description of the image here

Let's 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 excerpt results in the following impression:

x = 44
~x = 211

You can check the size that a variable occupies in C by calling the function sizeof(type). This function returns the size of the variable in bytes, so you have 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 excerpt results in the following print:

Tamanho do char é de 8 bits e 1 byte (s)

Because the char type in C is an 8-bit variable, when assigning x = 44 what you are doing is assigning a variable that contains the value 00101100. Or rather:

x = 44 é:
128| 64| 32| 16| 8| 4| 2| 1
  0|  0| 1 | 0 | 1| 1| 0| 0

Therefore, we have 32 + 8 + 4 which is equivalent to the 44 already mentioned. But when you pass the operation 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 inverse of 44 in an 8-bit variable is 211. An 8-bit variable stores 256 values, these values being from 0 to 255, so it can be said that when performing a negation, you get the remaining value at 255 (44 + 211 = 255).

Operation and.

The operation AND (E), also called a "conjunction", has the symbol * or . and returns 1 when, and only when, all bits are 1 (or true). In the language C this operation has the symbol & between two variables. Operation AND (or) is an operation that follows the following truth table:

insert the description of the image here

Let's now take the following code snippet:

y = x & 67;
printf("x & 67 = %d\n", y);

This excerpt results in the following impression:

x & 67 = 0

x it still equals 44, i.e. 00101100 in binary. When performing an operation AND with 67 (01000011 in binary) what is actually being done 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 line following.

Operation OR.

The operation OR (or), also called "disjunction", has the symbol +. This operation returns 1 when any of the bits is 1 and returns 0 when all the bits are 0. The operation OR is an operation that follows the following truth table:

insert the description of the image here

In the C language, 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 stretch results in the following impression:

x | 129 = 173

x which is worth 44, i.e. 00101100 in binary, is in a disjunction operation with 129 (10000001 in binary). When performing an operation OR between 44 and 129 what is actually being done 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 (or exclusive), also called " disjunction unique", 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 detector of differences between two logical operands. This operation follows the following truth table:

insert the description of the image here

The XOR operation is an interesting way to exchange the value of two variables without needing a third, as demonstrated by the excellent answer given by Lucas Nunes in this question .

In the C language, 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

Pois 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.

Bit offset.

In the C language, the operators >> or << are used to bit shift between variables to right or left. Bit shifting, as the name already says, is a technique of shifting 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 go into details about this in this answer.

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 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 will not delve much into this technique, but I recommend that you read the excellent answer of Lucas Nunes in this question, from which 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 code snippet above prints:

x <<2 = 176

Peas:

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 code snippet above print:

x >>2 = 11

Peas:

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.

Bit operations are often used when programming low level. You can configure microcontroller loggers and do code optimizations, for example. They are also used in encryption algorithms , because they are logical operations are less costly to the processor. In digital electronics, they are used at all times.

 11
Author: Avelino, 2017-04-13 12:59:38