What are logical operators and how do bit-to-bit operations work in the C language?

Asked

Viewed 2,493 times

9

What are logical operators NOT, AND, OR, XOR, in language C?

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

#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;
}
  • I don’t think so...

  • 1

    @user24857 if it is not duplicate, edit your question and explain what your doubts are, "I can’t understand this" is too generic.

  • I would like an explanation, I did not understand it. Because the result is ...?

  • I think he’d like a detailed explanation from each operator.

1 answer

12


Bit-to-bit operations, bit-to-bit operations, or binary logic, usually refer to logical operations done with binary numbers. These operations range from operations AND, OR, NOT, XOR, NOR, NAND, simple bit displacement, among other operations. It should be noted that some of these operations mentioned here are groupings of other operations, such as the NAND, which is a grouping of a logic AND with logic NOT. There are also interesting things to study, such as Boole algebra (or Boolean algebra) and the Theorems by De Morgan.

Operation NOT.

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

inserir a descrição da imagem aqui

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 section gives the following impression:

x = 44
~x = 211

You can check the size a variable occupies in C through the function call sizeof(type). This function returns the size of the variable in bytes, so you need 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 section gives the following impression:

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

By the fact of char type in C be an 8 bit variable when assigning x = 44 what is being done is to assign 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

Thus, we have 32 + 8 + 4 which is equivalent to the 44 already mentioned. But when the operation is over 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, being these values from 0 to 255, so it can be said that when making a negation, 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 the language C this operation has as symbol the & between two variables. The operation AND (OR) is an operation that follows the following truth table:

inserir a descrição da imagem aqui

Let us now take the following code snippet:

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

This section gives the following impression:

x & 67 = 0

x is still equivalent to 44, ie 00101100 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 amid 44 & 67 returns the number 0, printed on the next line.

Operation OR.

The operation OR (OR), 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:

inserir a descrição da imagem aqui

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 section gives the following impression:

x | 129 = 173

x worthwhile 44, that is to say 00101100 in binary, is in a disjunction operation with 129 (10000001 binary). When performing an operation OR amid 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 amid 44 & 129 returns the number 173, printed on the next line.

Operation XOR.

The operation XOR (Exclusive), also called "exclusive disjunction", 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:

inserir a descrição da imagem aqui

The XOR operation is an interesting way to change 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 the impression:

x ^167 = 139

For 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 amid 44 & 167 returns the number 139, printed on the next line.

Bit offset.

In the language C operators shall be used >> or << to move bits between variables to the right or left. Bit displacement, as the name already says, is a technique of moving bits to one or more houses. An interesting feature of bit shifting is that it is possible to multiply or divide the value of that variable, but I will not go into detail about this in this answer.

The bit offset 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 delve too deeply into this technique, but I recommend you read Lucas Nunes' excellent answer in this question, 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 code snippet above prints:

x <<2 = 176

For:

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 prints:

x >>2 = 11

For:

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. It is possible to configure microcontroller recorders and perform code optimizations, for example. They are also used in encryption algorithms, because they are logical operations are less expensive to the processor. In digital electronics, they are used at all times.

  • Hello would be able to put together with the related operation in the user question @user24857?

  • 2

    I’ll do it. You can let me do it right. ;)

  • Yes, but I didn’t understand the result ~x = 211 on that operator ~, which should just invert the bits?

  • I’m still writing your answer... everything will be clarified. I promise.

  • 101100 in reverse torque is 211, and in language c how do I find the size in binary?

  • These are the active digits of the binary number. I am added more content to the question, I will add why this too.

  • You can use the sizeof(tipo da variavel) to know its size in bytes. printf(" %d", (sizeof(int) * 8)) returns the value in bits.

  • 1

    Got it, well explained;

  • I think I’ll stop writing my answer here. If there are any more questions, please edit your question or put them in the comments. I hope I’ve helped.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.