In the beginning computers were basically just large calculators. And even today, that is basically what they are. They do thousands of calculations a second. Because of this, the most basic part of any programming language is a set of mathematical operation. We have already seen some, like addition +.

Let me list the basic algebraic operators (notice that there is no operator to square a number or raise it to a power):

- + add two values
- - subtract two values
- / divide two values
- * multiply two values
- % find the remainder after dividing the two values (called modulo or modulus )

Just to make this clearer, let me show you some examples:

Assume I have the **int a**, then

a = 7 + 8; // a is 15 a = 10 - 8; // a is 2 a = 7 * 8; // a is 56 a = 16 / 8; // a is 2 a = 35 / 8; // a is 4 (becauseais anint, C++ rounds a down to the nearest integer, we lose the decimal) a = 19 % 8; // a is 3 ( 19 / 8 is 2 remainder 3, using the % gives us the remainder)

There are also bitwise operators. What these operators do is manipulate the bits of a variable or perform logical operations on values. To understand this we need a little background about bits and bytes. You remember from chapter 1 that primitive data types have different sizes. We expressed this size difference in terms of how many bytes each data type had. A short for example is composed of two bytes, a long of four bytes. But what are bytes?

Normal mathematics that you have learned is decimal mathematics. The word decimal comes from the Latin word for ten. This is because normal mathematics is based a 10 digit number system. The digits start at 0 and go to 9. If you want to write a number larger than 9 you need to create another column and put a 1 in it. But imagine if you tried to express numbers with only two digits. Such a system would be called binary mathematic, from the Latin word for two. Your digits would go from 0 to 1. How would you express a number larger than 1? You would have to put a 1 in the next column (just as you did to express a number larger than 9). So, the number 2 would look like this 10. The number 3 would look like this 11. And the number 4 would need another new column like this 100. As you can see, we quickly need to start using a lot of columns. For example the number 255 would look like this 11111111.

Here is a list of some decimal numbers and their binary equivalents

1 | 1 |

2 | 10 |

3 | 11 |

4 | 100 |

5 | 101 |

6 | 110 |

7 | 111 |

8 | 1000 |

9 | 1001 |

10 | 1010 |

11 | 1011 |

12 | 1100 |

13 | 1101 |

14 | 1110 |

Computers represent numbers as binary values. Even if you assign a variable the perfectly normal decimal value like 9, the computer will store the value as a binary value ( 1001 ) You may never notice this because if you ever use the variable, the computer will convert the representation of the number back into decimal.

Each column in a binary number is called a **bit ** and a group of eight
**bit**s is called a **byte**. So if a **short **has two bytes,
(16 bits) then the maximum value it can contain is 1111 1111 1111 1111 binary or
65535 decimal. Every **char**, **int**, **float** etc. is
actually a set of bits and bytes. For instance, a **char** is 8 bits or one byte.
Usually, and **int** is 32 bits or 4 bytes. We can actually change variables
on the level of their bits. You can perform mathematics on numbers in terms of
their bits. To do this you must use what are called **bitwise operators**.
The idea of bitwise operators is to perform logical operation on bits in
parallel columns of two different numbers.

Here is a list of the basic bitwise operators:

- &
**bitwise and**operator - |
**bitwise or**operator - ^
**bitwise exclusive or**operator - < <
**left shift**operator - > >
**right shift**operator

The **bitwise and ( & ) **operator is like the regular** and ( && ) **
operator in that it evaluates two values and returns **true **or **false**.
Remember that **true** is equivalent to 1 and** false** to 0. So if
I write "1 & 1" I am asking are both digits **true**. In this case they
are both **true** (1) so the result is **true **(1). Similarly, "1 &
0" and "0 & 0" both result in **false **since it is not so that both values
in each comparison are **true**. In one case only one value is **true**,
and in the second case neither values are **true**; they are both 0.What we
are saying with the **& operator** is look for any place in the
2 sets of bits where there is a 1 in the same column of each number.
A column which has a 1 in both numbers will meet the **bitwise and**
( & ) condition. Therefore, that column in the resulting value will be
marked with a 1.

The **bitwise or** is **true** if one or more of the
values is **true**. So therefore, "1 | 1" and " 1| 0" are both **true**.
But " 0 | 0" is **false**. **Bitwise exclusive or **is **true **
when exactly one of the two values is **true**, but **false** if *both*
values are** true **or if *both* values are** false**. So,
"0 ^ 1" is **true **but " 0 ^ 0" and "1 ^ 1" are both **false**.

Let's see some examples. Assume I have the**
unsigned short a**, then

9 & 8;looks like this:

0000 0000 0000 1000 & 0000 0000 0000 1001 ------------- 0000 0000 0000 1000Similarly,

So what we actually wrote is:

0000 0000 0001 0011 | 0000 0000 0000 0101 -------------- 0000 0000 0001 0111How did we get to this result? Well,

Similarly,

What we actually wrote is:

0000 0000 0001 0011 ^ 0000 0000 0000 0101 -------------- 0000 0000 0001 0110As we know,

The last two
bitwise operators also work on the whole data type. What they do is to
move all the bits in the data type to the left or to the right. Thus, if I
have the **unsigned short a** =5; it would be represented in binary as
0000 0000 0000 0101. If I shifted the values one to the left I would get
0000 0000 0000 1010 or decimal value 10. If I reached the left most end of
the data type, I would shift the numbers right off the end and loose them.
Thus if I left shifted the number 1000 0000 0000 0000 (32768 decimal) I would
get 0000 0000 0000 00000 (0 decimal). Here is how to left shift a number
in C++:

unsigned short a=5; a<<1;// to shift the bits one space to the left a<<2;// to shift the bits two space to the left

Right shifting is conceptually the same thing as left shifting, but we move the digits tot eh right. This will result in making the value smaller. For example, if I shift the value 8 (0000 1000 binary) one digit to the right I will get 4. Here is how I would do it:

short a = 8; a = a>>1;If I shifted it 4 digits to the right I would get zero.

short a = 8; a = a>>4;

You may remember something called order of operations from mathematics. This is the relative precedence of the mathematical operations. For example, if you were asked to solve this problem, what would you write as the answer?

5+6*6If you remembered that multiplication comes before addition, you would get 5 + 36 or 41. But if you forgot that, you might do the addition first. In that case you would get a wrong answer, 66. Knowing what operation to do first is called knowing the order of operations. We can over-ride the order of operations by using paranthesis ( ). So for example,

a = 2 + 12 * 5 ; //a is 62

But

a = (2 + 12) * 5 ; //a is 70 So without going into too many examples I will present here a list of the operators we have seen so far in order from highest precedence to lowest:

- ( )
- !
- * / %
- + -
- << >>
- < <= > >=
- == !=
- ^
- |
- &&
- ||
- =

- Given a string of 1's and 0's , convert every set of 8 characters into their bit meaning and store in a single char. Thus given a string of 64 ones and zeros you could produce an eight letter string.

© Nachum Danzig July 2006