Scripting

Bitwise Operators in C Language

In this Linux Ways article, you’ll learn how to use the bitwise operators in C. We’ll show you a section that is dedicated to each of these operators where you’ll see their symbol, their expression, a truth table describing their logic, and a practical example with code snippets and images that show their usage.

You will also see how to assign the values in binary notation and we will show you the code of a function that displays in this notation the value of the variables that we will use in different examples.

You’ll also learn about short-circuit logic or minimum evaluation in bit-by-bit logic operations, so you’ll have a comprehensive knowledge and know which the best option for each need is when you need to perform the bitwise operations in C.

Bitwise Operators in the C Language

Bitwise operations can be logical or bit-shifting. The logical operations of this type are performed bit by bit on the binary basis of the variable. For example, in a logical operation between variables “a” and “b” that returns the result in “c”, the bit “0” of variable “a” operates on bit “0” of variable “b” and returns the result in bit “0” of variable “c”. In the following, we will see a table of bitwise operations and their operators in C:

Operation Operator Description
NOT ~ Returns the inverted value of a variable.
OR | Perform an OR operation between two variables.
AND & Perform an AND operation between two variables.
XOR ^ Perform an XOR operation between two variables.
Left shift << Shift n bits to the left.
Right shift >> Shift n bits to the right.
AND && Short circuit AND operation.
OR || Short circuit OR operation.

The logical NOT and shift operations are unary, which means that they operate on a single variable while the AND, OR, and XOR operations operate on two.

The bitwise operations are often used, for example, to mask multiple flags in a single variable which is then used as a flag input argument in functions.

To better understand the bitwise operations that we’ll see in this article, the next section provides tips to help you easily assign and display the values on the screen using binary notation.

How to Assign and View the Values with Binary Notation in the C Language

To assign the binary values to the variables in the C language, we must prefix the binary value with the notation base which is “0b”. In the following, we will see a fragment that declares the variable “a” of type unsigned char and assigns it with the value of 00011000.

unsigned char a = 0b00011000;

Now, let’s look at how we can make these values visible in the command console. The code that we see in the following belongs to a function that converts the unsigned char values that are sent in its input argument into binary notation strings and displays them on the screen:

void tobin (unsigned char a);

void tobin (unsigned char a)
{
   unsigned char mask= 0b10000000;
   unsigned char c;
   for (int bit=0; bit!=8; bit++)
     {
      c = a & mask;
      if ( c== 0 )
         printf( "0" );
      else
         printf( "1" );
      mask = mask >> 1;
      c = 0;
     }  printf ("\n");
  }

We store this simple function in a file named “tobin.c” in the directory where the main file is located, and it will help us see the results in binary notation of the examples that we will see in this article.

To use the function, we need to include it to the main file as follows:

#include "tobin.c"

The “~” Operator and Logical Bitwise NOT Operations

The operator that is used to perform the logical NOT operations is the “~” symbol. In the following, we see the expression that is used to perform this operations:

c =~ a;

The NOT operation inverts the value of the bit, giving 1 if the operated bit is 0, and 0 if it is 1. This type of operation is used to get the complement of a value. In the following, we see the truth table for this operation:

a ~ =
0 ~ 1
1 ~ 0

How to Perform a NOT Operation in the C Language

In this example, we will create the variables “a” and “c”, both of type unsigned char. The variable “c” stores the result of the NOT operation of the variable “a”. The binary value that we assign to this variable is 0b00011000 whose conversion to an integer is 24.

Then, we execute the NOT operation with the following expression:

c =~ a

Using the tobin() function, we display the original and resulting value on the screen in binary format. In the following, we see the code for this operation:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tobin.c

int main()

{

unsigned char a = 0b00011000;

unsigned char c;

tobin(a);

c =~a;

tobin(c);

}

In the following figure, we see the execution of this code, returning the value of “a” and the result of the operation in “c”:

The “&” Operator and Logical AND Operations in the C Language

The operator that is used to perform the logical AND operations is the “&” symbol.

In the following, we see the expression that is used to perform these logical operations between variables “a” and “b”:

c = a & b;

The AND operation returns 1 only when bits “a” and “b” are equal to 1, and 0 in other cases. In the following, we see the truth table for the AND operation:

a & b =
0 & 0 0
0 & 1 0
1 & 0 0
1 & 1 1

The logical AND operations are commonly used to clear the bits from a flag mask. For example, if we want to set the bit one of a mask to zero, we perform this operation between the mask and the “0b1111101” value. In this way, bit one is set to 0 while the rest retains its previous state.

How to Perform a Logical AND Operation in the C Language

In this example, we will see how to perform the AND operation between variables “a” and “b” and store the result in variable “c”.

We assign the “0b11101111” to variable “a” and the “0b01010011” value to variable “b”. Then, we perform the AND operation with the “&” operator. To display the values and results in binary notation, we call the tobin() function. In the following, we see the code for this example:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tobin.c"

void main()

{

unsigned char a = 0b11101111;

unsigned char b = 0b01010011;

unsigned char c;

tobin(a);

tobin(b);

printf ("--------\n");

c = a & b;

tobin(c);

}

The image that we see in the following shows the execution of this code:

As we can see, using the AND operations, we can clear the bits from a mask, this being the method to deselect the flags in variables that group several of them.

The “|”Operator and Logical OR Operations

The operator to perform the logical OR operations is the “|” symbol. In the following, we see the expression that is used to perform this logical operations between bits “a” and “b”:

c = a | b;

The OR operation results in 1 if bit “a” or bit “b” or both are equal to 1 and 0 if bit “a” and bit “b” are both equal to 0. In the following, we see the truth table for the OR operation:

a | b =
0 | 0 0
0 | 1 1
1 | 0 1
1 | 1 1

The bitwise OR operation is often used to create the flag masks in variables, grouping several of them.

How to Perform an OR Operation in the C Language

 

In this example, we will show you how to perform an OR operation between variables “a” and “b”, both of type unsigned char, and store the result in the variable “c”. We will assign the “0b000011” value to variable “a” and the “0b010101” value to variable “b”. Then, we perform the OR operation with the “|” operator.

Then, we call the tobin() function to see the status of the variables and its result. In the following, we see the code for this example:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include "tobin.c"

void main()

{

unsigned char a = 0b00000011;

unsigned char b = 0b01010101;

unsigned char c;

tobin(a);

tobin(b);

printf ("--------\n");

c = a | b;

tobin(c);

}

The image that we see in the following shows the execution of this code:

As we see, the use of OR operations is the method to configure the flags in variables by grouping several of them.

The “^” Operator and Logical XOR Operations

The operator to carry out the XOR logical operations is the “|” symbol.

In the following, we see the expression that is used to perform the XOR logical operations between bits “a” and “b”:

c = a ^ b;

The XOR operation results in 1 if bit “a” or bit “b” are equal to 1 and 0. But it results in 0 if both are equal to 0 or equal to 1. In the following, we see the truth table for the XOR operation:

a ^ b =
0 ^ 0 0
0 ^ 1 1
1 ^ 0 1
1 ^ 1 0

How to Perform a XOR Operation in the C Language

 

In this example, we will show you how to perform a XOR operation between variables “a” and “b”, both of type unsigned char, and store the result in variable “c”. We assign the “0b11010011” value to the variable “a” and the “0b01010101” value to “b”. Then, we operate the variables with the “^” operator and show the state of it with the tobin() function. In the following, you can see the code for this example:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include "tobin.c"

void main()

{

unsigned char a = 0b11010011;

unsigned char b = 0b01010101;

unsigned char c;

printf ("--------\n");

c = a ^ b;

tobin(a);

tobin(b);

tobin(c);

}

The image that we see in the following shows the execution of this code:

As we can see, the XOR operation behaves like an OR operation, except in cases where “a” and “b” are both equal to 1.

The “<<” and “>>” Operators for Bit Shifting

The “< <” and “> >” operators shift a number “n” bits of a variable to the left or right and fill the empty places with zeros.

The following is the expression that is used to perform the n-bit shifts to the left and to the right:

c = a << n;

c = a >> n;

How to Shift the Bits with the “<<” and “>>” Operators in the C Language

In this example, we will declare the variable “a” and assign it with the “0b0011000” value. Then, we will rotate two bits to the left and display the result on the screen with the tobin() function. Then, we move the bits again, but four positions to the right, and display the result. In the following, we can see the code for this example:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include "tobin.c"

void main()

{

unsigned char a = 0b00011000;

tobin(a);

a = a << 2;

tobin(a);

a = a >> 4;

tobin(a);

}

The image that we see in the following shows the execution of this code:


Logical Short Circuit Operations in the C Language

The bitwise operations are often used as input conditions in “if” conditions or even as escape conditions in loops. In these cases, we can perform a simple or compound bitwise operation.

When we use the compound operations, there are cases where the first expression determines the final result independently of the result of the other operations. We can see this in the following expression:

c = ( a & b ) & ( d & e )

Now, we replace the variables with bit values:

c = ( 0 & 1 ) & ( 1 & 1 )

In this case, the result in “c” is defined by the result =0 of the AND operation between “a” and “b”, independent of the result of the second operation.

The same happens with the following OR operation:

c = ( 0 | 1 ) | ( 1 & 1 )

In this expression, the result of the OR operation between “a” and “b” is equal to 1, which is why it also determines the result in “c”. While the result of the second operation has no influence on the final result.

For these cases, there is the possibility of performing the short-circuit operations. In this type of operation, the first expression is analyzed. If the result determines the final result, the program ignores the other expressions.

To perform the short-circuit operations, the double operators of the operation to be performed are used. We can see an expression that applies the short circuit logic in a compound AND operation in the following:

c = ( 0 | 1 ) && ( 1 & 1 )


Conclusion

In this Linux Ways article, we showed you how to use the operators available in C to perform the bitwise operations. In this article, we learned a table with the different operators available and then a section for each of them describing their function, the expression used, and how to use them with practical examples. We also provided you the tips that you need to handle the binary numbers and see their values on the screen so you can quickly understand the bitwise operations.

Similar Posts