C Bitwise Operators Examples – OR, AND, XOR, NOT, Left/Right Shift

by Lakshmanan Ganapathy on October 17, 2012

Bitwise operators are used to manipulate one or more bits from integral operands like char, int, short, long. In this article, we will see the basics of bitwise operators, and some useful tips for manipulating the bits to achieve a task. This article assumes that you know the basics of Truth Table for various operators.

C language supports the following bitwise operators.

  • | – Bitwise OR
  • & – Bitwise AND
  • ~ – One’s complement
  • ^ – Bitwise XOR
  • << – left shift
  • >> – right shift

Though we are calling it as a bitwise operators, it always operate on one or more bytes i.e, it will consider the whole representation of the number when applying bitwise operators. By using some techniques, we can manipulate a single bit on the whole representation of the number as we will see in later sections

Bitwise OR – |

Bitwise OR operator | takes 2 bit patterns, and perform OR operations on each pair of corresponding bits. The following example will explain it.

       1010
       1100
      --------
OR     1110 
      --------

The Bitwise OR, will take pair of bits from each position, and if any one of the bit is 1, the result on that position will be 1. Bitwise OR is used to Turn-On bits as we will see in later sections.

Bitwise AND – &

Bitwise AND operator &, takes 2 bit patterns, and perform AND operations with it.

       1010
       1100
      -------
AND    1000
      -------

The Bitwise AND will take pair of bits from each position, and if only both the bit is 1, the result on that position will be 1. Bitwise AND is used to Turn-Off bits.

One’s Complement operator – ~

One’s complement operator (Bitwise NOT) is used to convert each “1-bit to 0-bit” and “0-bit to 1-bit”, in the given binary pattern. It is a unary operator i.e. it takes only one operand.

       1001
NOT
      -------
       0110
      -------

Bitwise XOR – ^

Bitwise XOR ^, takes 2 bit patterns and perform XOR operation with it.

       0101
       0110
      ------
XOR    0011
      ------

The Bitwise XOR will take pair of bits from each position, and if both the bits are different, the result on that position will be 1. If both bits are same, then the result on that position is 0.

Left shift Operator – <<

The left shift operator will shift the bits towards left for the given number of times.

int a=2<<1;

Let’s take the binary representation of 2 assuming int is 1 byte for simplicity.

Position 7    6    5    4    3    2    1    0
Bits 0    0    0    0    0    0    1    0

Now shifting the bits towards left for 1 time, will give the following result

Position 7    6    5    4    3    2    1    0
Bits 0    0    0    0    0    1    0    0

Now the result in decimal is 4. You can also note that, 0 is added as padding the in the position 0.

If you left shift like 2<<2, then it will give the result as 8. Therefore left shifting 1 time, is equal to multiplying the value by 2.

Right shift Operator – >>

The right shift operator will shift the bits towards right for the given number of times.

int a=8>>1;

Let’s take the binary representation of 8 assuming int is 1 byte for simplicity.

Position 7    6    5    4    3    2    1    0
Bits        0    0    0    0    1    0    0    0

Now shifting the bits towards right for 1 time, will give the following result

Position 7    6    5    4    3    2    1    0
Bits 0    0    0    0    0    1    0    0

Now the result in decimal is 4. Right shifting 1 time, is equivalent to dividing the value by 2.

Note on shifting signed and unsigned numbers

While performing shifting, if the operand is a signed value, then arithmetic shift will be used. If the type is unsigned, then logical shift will be used.

In case of arithmetic shift, the sign-bit ( MSB ) is preserved. Logical shift will not preserve the signed bit. Let’s see this via an example.

#include<stdio.h>

int main() {
    signed char a=-8;
    signed char b= a >> 1;
    printf("%d\n",b);
}

In the above code, we are right shifting -8 by 1. The result will be “-4″. Here arithmetic shift is applied since the operand is a signed value.

#include<stdio.h>

int main() {
    unsigned char a=-8;
    unsigned char b= a >> 1;
    printf("%d\n",b);
}

Note: Negative number are represented using 2′s complement of its positive equivalent.

2's compliment of +8 is

1111 1000

Right shifting by 1 yields,

0111 1100 ( 124 in decimal )

The above code will result in 124 ( Positive value ). Here logical shift is applied since the operand is unsigned, and it won’t preserve the MSB of the operand.

In our next article in this series, we will see how we can use this bit-wise operators to perform various tasks like turning on/off a specific bit, finding odd/even number, etc.


Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 13 comments… read them below or add one }

1 Bob October 17, 2012 at 9:01 am

Thanks!!. Nothing like a refresher course. I liked it…

2 Richard Funderburk October 17, 2012 at 9:14 am

I believe that the statement “if the operand is a signed value, then arithmetic shift will be used. If the type is unsigned, then logical shift will be used” is compiler specific. From the ISO-C spec:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

3 Jalal Hajigholamali October 17, 2012 at 1:23 pm

Hi,

Thanks a lot….

4 siniranji October 17, 2012 at 7:17 pm

please take us slowly into reversing, xor is good and please teach us stack and all internal stuff

5 Mustapha Oldache October 18, 2012 at 2:43 am

Hi !

It could be helpful.

6 Chris October 18, 2012 at 6:31 am

Hello, I am not a programmer but sort of understand truth tables, interesting though.
I have just started my CCNA recently and an article on subnetting would be great.

7 Yuvaraj October 18, 2012 at 8:11 am

nice article.
+1 for Richard Funderburk for pointing out the spec.
In Richards comment there is small a error in dislplaying the expression “E1 / 2E2 ” . That is actually (E1)/ (2 power of E2) ( i.e E1 / 2 pow(E2)) . That looks like 2 multiplied by E2.

8 Thiago Jobson December 16, 2012 at 2:34 pm

Hello, nice article.

Can’t wait for the next one.

Thanks!

9 vignesh March 8, 2013 at 12:22 pm

thank you very much.

10 sachin July 24, 2013 at 2:09 am

good one……

11 saravanan October 25, 2013 at 9:09 am

goods

12 Carl Marx November 28, 2013 at 1:56 am

Buddy is there a book or something which will explain more of this with some more examples stuff and easy to understand for a newbie. Thank you

13 Anonymous April 9, 2014 at 8:53 am

its quite helpful

thanks

Leave a Comment

Previous post:

Next post: