13,007,176 members (58,309 online)
Add your own
alternative version

#### Stats

645.3K views
385 bookmarked
Posted 8 May 2002

# An introduction to bitwise operators

, 8 May 2002
 Rate this:
Please Sign up or sign in to vote.
This article gives a brief overview of C style bitwise operators

## Introduction

I have noticed that some people seem to have problems with bitwise operators, so I decided to write this brief tutorial on how to use them.

## An Introduction to bits

Bits, what are they you may ask?

Well, simply put, bits are the individual ones and zeros that make up every thing we do with computers. All the data you use is stored in your computer using bits. A BYTE is made up of eight bits, a WORD is two BYTEs, or sixteen bits. And a DWORD is two WORDS, or thirty two bits.

``` 0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0
||              |               |               |              ||
|+- bit 31      |               |               |       bit 0 -+|
|               |               |               |               |
+-- BYTE 3 -----+--- BYTE 2 ----+--- BYTE 1 ----+-- BYTE 0 -----+
|                               |                               |
+----------- WORD 1 ------------+----------- WORD 0 ------------+
|                                                               |
+--------------------------- DWORD -----------------------------+```

The beauty of having bitwise operators is that you can use a BYTE, WORD or DWORD as a small array or structure. Using bitwise operators you can check or set the values of individual bits or even a group of bits.

## Hexadecimal numbers and how they relate to bits

When working with bits, it is kind of hard to express every number using just ones and zeros, which is known as binary notation. To get around this we use hexadecimal (base 16) numbers.

As you may or may not know, it takes four bits to cover all the numbers from zero to fifteen, which also happens to be the range of a single digit hexadecimal number. This group of four bits, or half a BYTE, is called a nibble. As there are two nibbles in a BYTE, we can use two hexadecimal digits to show the value of one BYTE.

```NIBBLE   HEX VALUE
======   =========
0000        0
0001        1
0010        2
0011        3
0100        4
0101        5
0110        6
0111        7
1000        8
1001        9
1010        A
1011        B
1100        C
1101        D
1110        E
1111        F```

So if we had one BYTE containing the letter 'r' (ASCII code 114) it would look like this:

```0111 0010    binary
7    2     hexadecimal```

We could write it as '0x72'

## Bitwise operators

There are six bitwise operators. They are:
&   The AND operator
|   The OR operator
^   The XOR operator
~   The Ones Complement or Inversion operator
>>   The Right Shift operator
<<   The Left Shift operator.

### The & operator

The & (AND) operator compares two values, and returns a value that has its bits set if, and only if, the two values being compared both have their corresponding bits set. The bits are compared using the following table

```1   &   1   ==   1
1   &   0   ==   0
0   &   1   ==   0
0   &   0   ==   0
```

An ideal use for this is to set up a mask to check the values of certain bits. Say we have a BYTE that contains some bit flags, and we want to check if bit four bit is set.

```BYTE b = 50;
if ( b & 0x10 )
cout << "Bit four is set" << endl;
else
cout << "Bit four is clear" << endl;```

This would result in the following calculation

```  00110010  - b
& 00010000  - & 0x10
----------
00010000  - result
```

So we see that bit four is set.

### The | operator

The | (OR) operator compares two values, and returns a value that has its bits set if one or the other values, or both, have their corresponding bits set. The bits are compared using the following table

```1   |   1   ==   1
1   |   0   ==   1
0   |   1   ==   1
0   |   0   ==   0
```

An ideal use for this is to ensure that certain bits are set. Say we want to ensure that bit three of some value is set

```BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;```

This would result in the following calculation

```  00110010  - b
| 00000100  - | 0x04
----------
00110110  - result
```

### The ^ operator

The ^ (XOR) operator compares two values, and returns a value that has its bits set if one or the other value has its corresponding bits set, but not both. The bits are compared using the following table

```1   ^   1   ==   0
1   ^   0   ==   1
0   ^   1   ==   1
0   ^   0   ==   0
```

An ideal use for this is to toggle certain bits. Say we want toggle the bits three and four

```BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;```

This would result in the following calculations

```  00110010  - b
^ 00011000  - ^ 0x18
----------
00101010  - result

00101010  - b
^ 00011000  - ^ 0x18
----------
00110010  - result
```

### The ~ operator

The ~ (Ones Complement or inversion) operator acts only on one value and it inverts it, turning all the ones int zeros, and all the zeros into ones. An ideal use of this would be to set certain bytes to zero, and ensuring all other bytes are set to one, regardless of the size of the data. Say we want to set all the bits to one except bits zero and one

```BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;```

This would result in the following calculations

```00000011  - 0x03
11111100  - ~0x03  b

0000000000000011  - 0x03
1111111111111100  - ~0x03  w
```

Another ideal use, is to combine it with the & operator to ensure that certain bits are set to zero. Say we want to clear bit four

```BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;```

This would result in the following calculations

```  00110010  - b
& 11101111  - ~0x10
----------
00100010  - result
```

### The >> and << operators

The >> (Right shift) and << (left shift) operators move the bits the number of bit positions specified. The >> operator shifts the bits from the high bit to the low bit. The << operator shifts the bits from the low bit to the high bit. One use for these operators is to align the bits for whatever reason (check out the MAKEWPARAM, HIWORD, and LOWORD macros)

```BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;```

This would result in the following calculations

```00001100  - b
00110000  - b << 2
00000011  - b >> 2
```

## Bit Fields

Another interesting thing that can be done using bits is to have bit fields. With bit fields you can set up minature structures within a BYTE, WORD or DWORD. Say, for example, we want to keep track of dates, but we want to use the least amount of memory as possible. We could declare our structure this way

```struct date_struct {
BYTE day   : 5,   // 1 to 31
month : 4,   // 1 to 12
year  : 14;  // 0 to 9999
} date;```

In this example, the day field takes up the lowest 5 bits, month the next four, and year the next 14 bits. So we can store the date structure in twenty three bits, which is contained in three BYTEs. The twenty fourth bit is ignored. If I had declared it using an integer for each field, the structure would have taken up 12 BYTEs.

```|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|
|                           |       |         |
+------ year ---------------+ month +-- day --+```

Now lets pick this declaration apart to see what we are doing.

First we will look at the data type we are using for the bit field structure. In this case we used a BYTE. A BYTE is 8 bits, and by using it, the compiler will allocate one BYTE for storage. If however, we use more than 8 bits in our structure, the compiler will allocate another BYTE, as many BYTEs as it takes to hold our structure. If we had used a WORD or DWORD, the compiler would have allocated a total of 32 bits to hold our structure.

Now lets look at how the various fields are declared. First we have the variable (day, month, and year), followed by a colon that separates the variable from the number of bits that it contains. Each bit field is separated by a comma, and the list is ended with a semicolon.

Now we get to the struct declaration. We put the bit fields into a struct like this so that we can use convention structure accessing notation to get at the structure members. Also, since we can not get the addresses of bit fields, we can now use the address of the structure.

```date.day = 12;

dateptr = &date;
dateptr->year = 1852;```

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 President Canada
No Biography provided

## Comments and Discussions

 nice article ,u can add how bitwise ops can be combined Anonymous20-Sep-04 0:07 Anonymous 20-Sep-04 0:07
 Can i use the declaration? mahmutarik22-Mar-04 3:32 mahmutarik 22-Mar-04 3:32
 error C2034: 'year' : type of bit field too small for number of bits Lee McKenzie13-Mar-04 3:50 Lee McKenzie 13-Mar-04 3:50
 Re: error C2034: 'year' : type of bit field too small for number of bits leekillestein17-Jun-04 11:52 leekillestein 17-Jun-04 11:52
 Re: error C2034: 'year' : type of bit field too small for number of bits John R. Shaw14-May-07 18:49 John R. Shaw 14-May-07 18:49
 Re: error C2034: 'year' : type of bit field too small for number of bits islandscape14-Oct-09 3:03 islandscape 14-Oct-09 3:03
 Re: error C2034: 'year' : type of bit field too small for number of bits Atul Khanduri17-Feb-14 5:37 Atul Khanduri 17-Feb-14 5:37
 Nice Article saurabhbajaj27-Nov-03 22:17 saurabhbajaj 27-Nov-03 22:17
 I Get something in this article AfxMessageBox8-Sep-03 3:44 AfxMessageBox 8-Sep-03 3:44
 I Learned Bit Fields To Be the Best!
 TKS xhight2-Sep-03 8:16 xhight 2-Sep-03 8:16
 Re: TKS PJ Arends2-Sep-03 8:33 PJ Arends 2-Sep-03 8:33
 Great MessnerEW23-Jul-03 20:36 MessnerEW 23-Jul-03 20:36
 Re: Great manzoor1012-Dec-08 4:12 manzoor10 12-Dec-08 4:12
 we did it again Jeremy Falcon25-Jun-03 5:33 Jeremy Falcon 25-Jun-03 5:33
 Re: we did it again PJ Arends25-Jun-03 6:54 PJ Arends 25-Jun-03 6:54
 Nibble Swap Bcdarus1-Jun-03 18:36 Bcdarus 1-Jun-03 18:36
 Re: Nibble Swap PJ Arends2-Jun-03 5:40 PJ Arends 2-Jun-03 5:40
 ASL vs ROL Kochise25-Jun-03 5:21 Kochise 25-Jun-03 5:21
 Re: ASL vs ROL PJ Arends25-Jun-03 6:40 PJ Arends 25-Jun-03 6:40
 Mistyping... Kochise25-Jun-03 22:49 Kochise 25-Jun-03 22:49
 Re: Mistyping... Ryan Binns30-Jun-03 23:02 Ryan Binns 30-Jun-03 23:02
 Re: Mistyping... Kochise1-Jul-03 0:26 Kochise 1-Jul-03 0:26
 * bookmarked * Nitron4-Feb-03 4:33 Nitron 4-Feb-03 4:33
 Good Starting point KarstenK12-Nov-02 1:26 KarstenK 12-Nov-02 1:26
 Thanks a lot poplarc3-Nov-02 19:54 poplarc 3-Nov-02 19:54
 Good article Nilesh K. Karkhanis10-Oct-02 23:45 Nilesh K. Karkhanis 10-Oct-02 23:45
 Gsm software loni8-Sep-02 8:29 loni 8-Sep-02 8:29
 BIG Endian vs little Endian Kochise22-Aug-02 23:09 Kochise 22-Aug-02 23:09
 How to know? richard sancenot8-Sep-05 23:00 richard sancenot 8-Sep-05 23:00
 A minor correction... Gurj13-Jun-02 12:54 Gurj 13-Jun-02 12:54
 Re: A minor correction... PJ Arends13-Jun-02 14:18 PJ Arends 13-Jun-02 14:18
 Thanks...... Mazdak23-May-02 21:52 Mazdak 23-May-02 21:52
 Re: Thanks...... PJ Arends24-May-02 6:23 PJ Arends 24-May-02 6:23
 Re: Thanks...... Mazdak24-May-02 8:42 Mazdak 24-May-02 8:42
 Re: Thanks...... Tim Smith24-May-02 8:52 Tim Smith 24-May-02 8:52
 Re: Thanks...... Mazdak24-May-02 19:07 Mazdak 24-May-02 19:07
 Great but.... johny quest19-May-02 18:16 johny quest 19-May-02 18:16
 Re: Great but.... PJ Arends20-May-02 7:44 PJ Arends 20-May-02 7:44
 Date_struct KarstenK13-May-02 20:41 KarstenK 13-May-02 20:41
 Valuable article!! WREY12-May-02 10:03 WREY 12-May-02 10:03
 Great article Jim Crafton9-May-02 16:21 Jim Crafton 9-May-02 16:21
 Re: Great article Steve Chen9-May-02 19:10 Steve Chen 9-May-02 19:10
 Re: Great article poplarc3-Nov-02 20:07 poplarc 3-Nov-02 20:07
 Bitfield portability Pravin Wagh9-May-02 10:16 Pravin Wagh 9-May-02 10:16
 Re: Bitfield portability ilinov10-May-02 3:53 ilinov 10-May-02 3:53
 swap X, Y without 3rd var Y. Huang9-May-02 7:56 Y. Huang 9-May-02 7:56
 Re: swap X, Y without 3rd var jfugate9-May-02 8:35 jfugate 9-May-02 8:35
 Re: swap X, Y without 3rd var Y. Huang9-May-02 10:31 Y. Huang 9-May-02 10:31
 Re: swap X, Y without 3rd var Atlantys10-May-02 2:59 Atlantys 10-May-02 2:59
 Re: swap X, Y without 3rd var Joao Vaz10-May-02 3:13 Joao Vaz 10-May-02 3:13
 Last Visit: 31-Dec-99 18:00     Last Update: 29-Jun-17 4:50 Refresh 123 Next »

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170628.1 | Last Updated 9 May 2002
Article Copyright 2002 by PJ Arends
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid