There are four "basic" or important binary operations; AND, OR, XOR and NOT.

Fundamentally, these really operate on a single bit.

A AND B is True if and only if both A and B are True.

A OR B is True if and only if at least one of A and B are True.

A XOR B is True if and only if A and B are different (precisely one is True).

NOT A is True if A is False and vice versa.

When we come to deal with computers, we operate on bytes, words, dwords, etc.

The bitwise operations apply their operation to each bit-pair of the operands.

e.g.

A = a

_{1}a

_{2}a

_{3}a

_{4}B = b

_{1}b

_{2}b

_{3}b

_{4}Then A & B = (a

_{1} AND b

_{1}), (a

_{2} AND b

_{2}), (a

_{3} AND b

_{3}), (a

_{4} AND b

_{4})

Going back to the previous example:

Code: Select all

`x = 0xF3 //(= 11110011)`

y = 0xA5 //(= 10100101)

x & y = 0xA1 (= 10100001)

Starting from the right-most bit (least significant bit, or the "zeroth" bit), we see that it's 1 for both x and y, so the zeroth bit for x&y is 0.

For the next bit, we see it's 0 for y, so x&y's next bit must be 0. Similarly, the next two must be 0 since one is 0 for x and the one after is 0 for y.

We can see the top four bits of x are all 1, so the top bits of x&y are going to be whatever the top four bits of y are.

Code: Select all

`x = 1 1 1 1 0 0 1 1`

y = 1 0 1 0 0 1 0 1

x & y = 1 0 1 0 0 0 0 1

As for practical use?

Well AND is often used for masking; i.e "ignoring" part of a number.

So suppose I have some 32 bit integer and I'm only interested in the low word (the least significant 16 bits), then I simply mask the most significant 16 bits away.

Code: Select all

`int x = 231512351; //I want the bottom 16 bits`

int y = x & 0x0000FFFF //in hexadecimal, an F means "four on bits and no off bits"

//y = 39199 = 0x991F

This might come up if I'm reading data from a file using a binary file format (non-text); whether a particular bit is on or not in some byte can carry meaning.

XOR is often used to "flip" bits

For instance, in ASCII, upper case letters occupy the range 0x41 - 0x5A (65 to 91) whilst lower case letters are in the range 0x61-0x7A (97-122).

i.e. the difference between 'A' and 'a' is 32 (0x20) - with 'A', the 5th bit is off, with 'a' it's on.

So I can convert an upper case character to a lower case character and vice versa simply by inverting that bit.

Code: Select all

`char x = 'a';`

char y = x ^ 32;

//x = 'A';

OR is used to force particular bits on; often when merging flags or building up numbers from individual bits or bytes (although it's often equivalent to simple addition).