Bitwise Operators in C

An Arithmetic logic unit (which is within the CPU), mathematical operations like addition, subtraction, multiplication, and division are done in bit-level. To perform bit-level operations bitwise operators in C language used.

Bitwise operators work on bits. These operators operate only on integers, not floating-point numbers. Bitwise operators are low-level programming language features. The bitwise operations are most often find application in device drivers such as modem programs, disk file routines, and printer routines.

Bitwise AND Operator(&)

The output of bitwise AND is 1 if the corresponding bits of two operands is 1. If either bit of an operand is 0, the result of the corresponding bit is evaluated to 0. Bitwise AND operator is denoted by &.

Bitwise AND truth table

P Q P&Q
0 0 0
0 1 0
1 0 0
1 1 1

The bitwise AND operation of two integers 14 and 27,
14 = 00001110 (In Binary)
27 = 00011011 (In Binary)
Bit Operation of 14 and 27
00001110 & 00011011 = 00001010 = 10 (In decimal)

#include<stdio.h>
int main()
{
  int a=14, b=27;
  printf("14 & 17 = %d\n", a&b);
  return 0;
}

Output:-

14 & 17 = 10

Important point:-

The & operator can be used to quickly check if a number is odd or even
The value of the expression (x & 1) would be non-zero only if x is odd, otherwise, the value would be zero.

#include<stdio.h>
int main()
{
   int x=5;
   (x&1)?printf("Odd"):printf("Even");
   return 0;
}
//Output:- Odd

Bitwise OR Operator (|)

The output of bitwise OR is 1 if at least one corresponding bit of two operands is 1. In C Programming, bitwise OR operator is denoted by |.

Bitwise OR truth table

P Q P | Q
0 0 0
0 1 1
1 0 1
1 1 1

14 = 00001110 (In Binary)
27 = 00011011 (In Binary)
Bitwise OR Operation of 14 and 27,
00001110 | 00011011 = 00011111 = 31 (In decimal)

#include<stdio.h>
int main()
{
  int a=14, b=27;
  printf("14 | 17 = %d\n", a|b);
  return 0;
}

Output:-

14 | 17 = 31

Bitwise XOR operator (^)

The result of bitwise XOR (exclusive OR) operator is 1 if the corresponding bits of two operands are opposite. It is denoted by ^.

Bitwise XOR truth table

P Q P ^ Q
0 0 0
0 1 1
1 0 1
1 1 0

Bitwise XOR Operation of 14 and 27,
14 = 00001110 (In Binary)
27 = 00011011 (In Binary)
00001110 ^ 00011011 = 00010101 = 21 (In decimal)

#include<stdio.h>
int main()
{
  int a=14, b=27;
  printf("14 ^ 17 = %d\n", a^b);
  return 0;
}

Output:-

14 ^ 17 = 21

The bitwise XOR operator is the most useful operator from a technical interview perspective. See:- Different methods for Swapping of two integers

Complement Operator (~)

Bitwise complement operator is a unary operator (works on only one operand). In complement operator, the bits are complemented i.e. 1’s become 0’s and 0’s become 1’s. Due to this +ve number becomes -ve number and -ve number becomes +ve. It is denoted by ~.

Bitwise NOT truth table

P ~ P
0 1
1 0

The Bitwise complement of any number N is -(N+1).

#include<stdio.h>
int main()
{
   printf("complement = %d\n", ~ 35);
   printf("complement = %d\n", ~ -12);
   return 0;
}

Output:-

complement = -36
complement = 11

Twist in bitwise complement operator:-

35 = 00100011 (In Binary)
Bitwise complement Operation of 35 = ~ (00100011) = 11011100 = 220 (In decimal)
The bitwise complement of 35 (~35) is -36 instead of 220, but why?
For any integer n, a bitwise complement of n will be -(n+1).
To understand this, you should have the knowledge of 2’s complement.

2’s Complement

Two’s complement is an operation on binary numbers. The 2’s complement of a number is equal to the complement of that number plus 1. For example:
Decimal Binary 2’s complement
0 00000000 -(11111111+1) = -00000000 = -0(decimal)
1 00000001 -(11111110+1) = -11111111 = -256(decimal
12 00001100 -(11110011+1) = -11110100 = -244(decimal
220 11011100 -(00100011+1) = -00100100 = -36(decimal)

Note: Overflow is ignored while computing 2’s complement.
The bitwise complement of 35 is 220 (in decimal). The 2’s complement of 220 is -36.

Hence, the output is -36 instead of 220.
The bitwise complement of any number N is -(N+1). Here’s how:
The bitwise complement of N = ~N (represented in 2’s complement form)
2’complement of ~N= -(~(~N)+1) = -(N+1)

Important point:-

The ~ operator should be used carefully. The result of ~ operator on a small number can be a big number if the result is stored in an unsigned variable, And the result may be a negative number if the result is stored in a signed variable. (assuming that the negative numbers are stored in 2’s complement form where the leftmost bit is the sign bit).

Bitwise Operators in C Shift Operators

Bit-shift operations can be very useful when we are decoding input from an external device, like a D/A converter, and reading status information. There are two shift operators in C programming:
1)Right shift operator
2)Left shift operator.

Right Shift Operator (>>)

Right shift operator shifts all bits towards the right by a certain number of specified bits. It is denoted by >>.

200 = 11001000
200>>1 = 01100100 [Right shift by one bit]
200>>2 = 00110010 [Right shift by two bits]
200>>5 = 00000110 [Right shift by five bits]
200>>8 = 00000000 [Right shift by eight bits]
200>>0 = 11001000 (No Shift)

#include<stdio.h>
int main()
{
   int num=200, i;
   for (i=0; i<=3; ++i)
   {
      printf("Right shift by %d bits: %d\n", i, num >> i);
   }
   return 0;
}

Output:-

Right shift by 0 bit: 200
Right shift by 1 bit: 100
Right shift by 2 bits: 50
Right shift by 3 bits: 25

Shifting the bit of an integer by one position to the Right is equivalent to dividing by 2. So that shifting the bits by n positions to the right is equivalent to division by 2n

 #include<stdio.h> 
 int main()
 {
   int x=20, y=-20;
   printf("%d %d\n", x>>1, y>>1);
   printf("%d %d\n", x>>2, y>>2);
   printf("%d %d\n", x>>3, y>>3);
   printf("%d %d\n", x>>4, y>>4);
   printf("%d %d\n", x>>5, y>>5);
   printf("%d %d\n", x>>6, y>>6);
   printf("%d %d\n", x>>7, y>>7);
   return 0;
 }

Output:-

10 -10
5 -5
2 -3
1 -2
0 -1
0 -1
0 -1

Left Shift Operator (<<)

Left shift operator shifts all bits towards left by a certain number of specified bits. It is denoted by <<.

200 = 11001000
200<<1 = 110010000 [Left shift by one bit]
200<<4 = 110010000000 [Left shift by four bit]
200<<0 = 11001000 (Shift by zero bit)

#include<stdio.h>
int main()
{
   int num=200, i;
   for (i=0; i<=3; ++i)
   {
      printf("Left shift by %d bits: %d\n", i, num << i);
   }
   return 0;
}

Output:-

Left shift by 0 bit: 200
Left shift by 1 bit: 400
Left shift by 2 bits: 800
Left shift by 3 bits: 1600

Shifting the bit of an integer by one position to the left is equivalent to multiplying by 2. So that shifting the bits by n positions to the left is equivalent to multiplication by 2n

Important points for Shift Operators:-

1)The left shift and right shift operators should not be used for negative numbers. If any of the operands is a negative number, it may result in undefined behaviour.
200<<-1 , 200 >> -1, -200 << 1 and -200 >> 1 are undefined.

2) Don’t shift more bits than exist in the operand.
If the number is shifted more than the size of an integer, the behavior is undefined. for example, 2 << 40 is undefined if integers are stored using 32 bits.

#include<stdio.h>
int main()
{
   int x=20, y=-20;
   printf("%d %d\n", x<<1, y<<1);
   printf("%d %d\n", x<<2, y<<2);
   printf("%d %d\n", x<<3, y<<3);
   printf("%d %d\n", x<<4, y<<4);
   printf("%d %d\n", x<<5, y<<5);
   printf("%d %d\n", x<<6, y<<6);
   printf("%d %d\n", x<<7, y<<7);
   return 0;
}

Output:-

40 -40
80 -80
160 -160
320 -320
640 -640
1280 -1280
2560 -2560

Find the output of the below program

#include<stdio.h>
int main()
{
   printf("%d\n",10<<2+3>>2);
   return 0;
}

Output:-

80

The arithmetic operator + has more precedence from the right shift (<<) operator and the left shift (>>) operator. right shift (<<) operator has more precedence from left shift (>>) operator. So, it can be written as (10<<(2+3))>>2

Some Points on Bitwise Operators in C

The bitwise operators should not be used in place of logical operators.
The result of logical operators (&&, || and !) is either 0 or 1, but bitwise operators return an integer value. Also, the logical operators consider any non-zero operand as 1.

#include<stdio.h>
int main()
{
   printf("%d ", 5 & -5);
   printf("%d ", 5 | -5);
   printf("%d ", 5 ^ -5);
   printf("%d ", 5 && -5);
   printf("%d", 5 || -5);
   return 0;
}

Output:-

1 -1 -2 1 1

Some Special small programs based on the bitwise operators in C

Program1:- Add two number without using + operator in C

//Add two number without using + operator in C
#include<stdio.h>
int main()
 {
   int a=5,b=15;
   printf("%d ", a-(-b));
   printf("%d", a-(~b)-1);
   return 0;
}
//Output:- 20 20

Program2:- Double an integer number without using arithmetic operators

//Duble a integer number without using an arithmetic operators
#include<stdio.h>
int main()
{
   int a=5;
   printf("%d ", a<<1);
   return 0;
}
//Output- 10

Program3:- Divide a number by 2 without using arithmetic operators

//Divide a number by 2 without using an arithmetic operators
include<stdio.h>
int main()
{
   int a=50;
   printf("%d ", a>>1);
   return 0;
}
//Output:- 25

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or you find anything incorrect? Let us know in the comments. Thank you!

Test Your Knowledge:-

Leave a Comment

Your email address will not be published. Required fields are marked *