Wednesday, 1 April 2015

Bitwise operators with examples in C++

Bitwise operators with examples in Cpp with code examples:

Byte is the lowest level at which we can access data; there is no "bit" type.
And also it is not possible to perform operations on a single bit -- every bitwise operator will be applied to, at a minimum, an entire byte at a time.

Using bitwise operators, it is possible to write functions that allow us to compact 8 Booleans into a single byte-sized variable, enabling significant memory savings at the expense of more complex code. In the past, this was a good trade-off. Today, at least for application programming, it is probably not.

Representation of the Symbol

Name of the Function

Symbol Description
~
Complement
Bit n of ~a is the opposite of bit n of a
&
Bitwise And
Bit n of a&b is 1 if bit n of a and bit n of b is 1.
|
Bitwise Or
Bit n of a|b is 1 if bit n of a or bit n of b is 1.
^
Bitwise Exclusive Or
Bit n of a^b is 1 if bit n of a or bit n of b is 1 but not if both are 1.
a^b = (a|b) & !(a&b) : either a or b but not both
>> 
Right Shift (divide by 2)
Bit n of a>>s is bit n-s of a.
<< 
Left Shift (multiply by 2)
Bit n of a<<s is bit n+s of a.

bitwise Complement: The bitwise complement operator, the tilde, ~, flips every bit. It is also called as twiddle, and the bitwise complement twiddles every bit:

This turns out to be a great way of finding the largest possible value for an unsigned number
unsigned int test = ~0;

bitwise AND: The bitwise AND operator is a single ampersand: &:
01001000 &

10111000 =

--------

00001000


bitwise OR: The bitwise OR operator is a |:
01001000 |

10111000 =

--------

11111000


bitwise Exclusive OR (XOR): if either one or the other of the inputs is a 1 the exclusive-or operator returns 1, but not if both are. That is, if both inputs are 1 or both inputs are 0, it returns 0.
Bitwise exclusive-or, with the operator of a carrot, ^, performs the exclusive-or operation on each pair of bits.
01110010 ^

10101010

--------

11011000

Suppose, we have some bit, either 1 or 0, that we'll call Z. When we take Z XOR 0, then we always get Z back: if Z is 1, we get 1, and if Z is 0, we get 0. On the other hand, when we take Z XOR 1, we flip Z. If Z is 0, we get 1; if Z is 1, we get 0:
TestBits ^ 0 : No change
TestBits ^ 1 : Flip
It's a kind of selective twiddle(~).So, if we do XOR against 111...1111, all the bits of TestBits flipped. Which is the equivalent of doing twiddle(~).
right shift operator (>>): Moving all the bits of a number a specified number of places to the right. Note that a bitwise right-shift will be the equivalent of integer division by 2:
00000101(5)  >>  1
--------
00000010(2)

left shift operator (<<): Moving all the bits of a number a specified number of places to the left:
[myVariable]<<[number of places]

Suppose we have number 8 written in binary 00001000. If we wanted to shift it to the left 2 places, we'd end up with 00100000; everything is moved to the left two places, and zeros are added as padding. This is the number 32:
00001000(8)  <<  2

--------

00100000(32)

Actually, left shifting is the equivalent of multiplying by a power of two:
val << num

--------

val * (1 << num)

More specifically:
8 << 2

--------

8 * (1 << 2)

--------

8 * (2**2)

--------

32

Set a bit (where n is the bit number, and 0 is the least significant bit):
 unsigned char Testbit |= (1 << n);
Try tot understand the below Example:
Testbit               1 0 0 0 0 0 0 0

Testbit |= (1 << 1) = 1 0 0 0 0 0 1 0

Testbit |= (1 << 3) = 1 0 0 0 1 0 0 0

Testbit |= (1 << 5) = 1 0 1 0 0 0 0 0

Clear a bit:
 unsigned char TestBit &= ~(1 << n);



See the sample below:

TestBit                1 1 1 1 1 1 1 1

TestBit &= ~(1 << 1) = 1 1 1 1 1 1 0 1

TestBit &= ~(1 << 3) = 1 1 1 1 0 1 1 1

TestBit &= ~(1 << 5) = 1 1 0 1 1 1 1 1

See the another sample for more understanding: Write a macro with two arguments a and pos, where a is a byte and the pos specifies a bit position of the byte. The macro should clear the particular bit position in the given byte.
#include <stdio.h>

using namespace std;



#define CLEARBIT(x, y) (x &= ~(1 << num) )



int main()

{

 /* 'z': decimal value 122 (=01111010) */

 char val = 'z'; 



 /* clearing the 5th bit */

 char aOut = CLEARBIT(val, 5);



 /* aOut = 'Z': decimal value 90 (=01011010) */

 printf("aOut=%c\n", aOut);



 return 0;

}

Toggle a bit:
 unsigned char Testbit ^= (1 << num)
Let us understand the below Example:
Testbit               1 0 0 1 1 0 1 1

Testbit ^= (1 << 1) = 1 0 0 1 1 0 0 1

Testbit ^= (1 << 3) = 1 0 0 1 0 0 1 1

Testbit ^= (1 << 5) = 1 0 1 1 1 0 1 1
Test a bit:
unsigned char Test = dVal & (1 << n); //dVal has the byte value.
The right/left most byte: unsigned char ShiftRight= Result & 0xff; // right most byte which is also called as least significant. unsigned char ShiftLeft = (Result>>8) & 0xff; // left most byte which is also called as most significant. sign bit assuming 16 bit, 2-byte short integer, two's complement:
bool signbit = Result & 0x8000; // This is the sign bit

No comments: