Basic Operations
Storing Integers
We’ve already said that computers used binary notation, integers are “whole numbers” so surely integers are just stored as their binary equivalent right? Well it isn’t quite that simple, we have a couple of complications to consider.
Unsigned Integers
Lets consider the simplest case. We want to store an integer number, we know the number will be positive or zero. In this case we can simply store the number in binary.
In most languages we have three types of integer data types - short, int and log.
Data Type | Size |
---|---|
short | 2 bytes |
int | 4 bytes |
long | 8 bytes |
However short, int and long can also store negative numbers. If we know the number is positive or zero we can use the keyword unsigned. This allows us to use all the bits to represent the integer.
Data Type | Size | Range |
---|---|---|
unsigned short | 2 bytes | 0 - 65,535 |
unsigned int | 4 bytes | 0 - 4,294,967,295 |
unsigned long | 8 bytes | 0 - 18,446,744,073,709,551,615 |
Overflow Errors
Unsigned integers are generally straight forward but there are two situations which require careful consideration.
What happens if you are storing 65,535 in an unsigned short and add 1 to it?
65,535 = 1111 1111 1111 1111
65,536 = 1 0000 0000 0000 0000
The maths is easy enough but the problem is an unsigned short only has 16 bits of data in it. The number is too big to be stored in the data type. What happens varies by language but generally you will be allowed to do this. A flag will be set to let you know an overflow has occurred but the programme will continue running.
The code below is in c, we’ll learn about c before long but this should be easy to follow.
unsigned short int aNumber=65535;
printf("the number is %hu\n", aNumber);
aNumber = aNumber + 1;
printf("the number is now %hu\n", aNumber);
Produces
the number is 65535
the number is now 0
Similarly if the numnber is zero and we subtract one.
unsigned short int aNumber=0;
printf("the number is %hu\n", aNumber);
aNumber = aNumber - 1;
printf("the number is now %hu\n", aNumber);
Produces
the number is 0
the number is now 65535
We say the numbers wrap-around. The wrap-around when we put a number in that is too big is obvious but why does subtracting 1 from 0 have this effect? It is caused by the way we store negative numbers.
Signed Integers - Storing Negative Numbers
As described above, most languages we have three types of integer data types - short, int and log.
Data Type | Size |
---|---|
short | 2 bytes |
int | 4 bytes |
long | 8 bytes |
We’ll shift the range of numbers so that 0 is in the middle.
Data Type | Size | Range | Data Type | Size | Range |
---|---|---|---|---|---|
unsigned short | 2 bytes | 0 - 65,535 | short | 2 bytes | -32,768 to 32,767 |
unsigned int | 4 bytes | 0 - 4,294,967,295 | int | 4 bytes | -2,147,483,648 to 2,147,483,647 |
unsigned long | 8 bytes | 0 - 18,446,744,073,709,551,615 | long | 8 bytes | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
We need some way to distinguish negative numbers from positive numbers. The approach taken was to use the leftmost bit to indicate the sign of the number. 0 means a positive number, 1 means a negative number.
(Too) Simple Negatives
Lets try simply using the left hand bit as a sign indicator. We end up with these numbers.
0 = positive 1 = negative
Too Simple Binary
Binary | Decimal | Binary | Decimal |
---|---|---|---|
0000 | 0 | 1000 | -0 |
0001 | 1 | 1001 | -1 |
0010 | 2 | 1010 | -2 |
0011 | 3 | 1011 | -3 |
0100 | 4 | 1100 | -4 |
0101 | 5 | 1101 | -5 |
0110 | 6 | 1110 | -6 |
0111 | 7 | 1111 | -7 |
First off we’ve got two zeroes and one of them is negative. That’s weird and it’s not good, it means we’ll need to check for both zeroes.
How does addition work? What if we add a positive and negative number together?
7 + -3 | ||||
---|---|---|---|---|
7 | 0 | 1 | 1 | 1 |
plus | ||||
-3 | 1 | 0 | 1 | 1 |
equals | ||||
add “units” together (20=1) | 1+1 | |||
10 | ||||
carry the multiple of 2 | 1 | 0 | ||
add “twos” together (21=2) | 1+1+1 | 0 | ||
1+1+1=3, 3 in binary is 11 | 11 | 0 | ||
carry the multiple of 2 | 1 | 1 | 1 | |
add “fours” together (22=4) | 1+0+1 | 1 | 0 | |
10 | 1 | 0 | ||
carry the multiple of 2 | 1 | 0 | 1 | 0 |
add “fours” together (22=4) | 0+1+1 | 0 | 1 | 0 |
10 | 0 | 1 | 0 | |
carry sets a flag | 0 | 0 | 1 | 0 |
Sum | 0 | 0 | 1 | 0 |
7 + -3 = 2 ?!?!
So simple binary addition doesn’t work if we simply use the left hand bit to indicate sign.
1s Complement
Let’s try a different approach. Lets say for a negative number we take the positive number and invert every bit - swap 1s for 0s and 0s for 1s.
1s Complement
Binary | Decimal | Binary | Decimal |
---|---|---|---|
0000 | 0 | 1111 | -0 |
0001 | 1 | 1110 | -1 |
0010 | 2 | 1101 | -2 |
0011 | 3 | 1100 | -3 |
0100 | 4 | 1011 | -4 |
0101 | 5 | 1010 | -5 |
0110 | 6 | 1001 | -6 |
0111 | 7 | 1000 | -7 |
We’ve still got two zeroes, but how does the maths work out?
7 + -3 | ||||
---|---|---|---|---|
7 | 0 | 1 | 1 | 1 |
plus | ||||
-3 | 1 | 1 | 0 | 0 |
equals | ||||
add “units” together (20=1) | 1+0 | |||
1 | ||||
add “twos” together (21=2) | 1+0 | 0 | ||
1 | 1 | |||
add “fours” together (22=4) | 1+1 | 0 | 0 | |
10 | 1 | 1 | ||
carry the multiple of 2 | 1 | 0 | 1 | 1 |
add signs together | 1+1 | 0 | 1 | 1 |
10 | 0 | 1 | 1 | |
The carry here sets a flag | 0 | 0 | 1 | 1 |
Sum | 0 | 0 | 1 | 1 |
7 + -3 = 3 ?!? Still not right. But watch what happens if we add a new rule. The rule is if after adding all the digits together the flag is set then add one to the sum. So we have an extra step.
7 + -3 | ||||
---|---|---|---|---|
… | … | … | … | |
carry flag set | 0 | 0 | 1 | 1 |
0 | 0 | 1 | 1 | |
+ | ||||
0 | 0 | 0 | 1 | |
1+1 | ||||
1 | 0 | |||
1+1 | 0 | |||
1 | 0 | 0 | ||
0+0 | 1 | 0 | 0 | |
0 | 1 | 0 | 0 | |
Sum | 0 | 1 | 0 | 0 |
7 + -3 = 4 ! Success
But we’ve still got two zeroes and that carry bit is a pain to deal with.
2s Complement
Let’s try 2s Complement. 2s Complement is 1s Complement + 1
2s Complement
Binary | Decimal | Binary | 1s Comp | 2s Comp : 1s Comp +1 |
---|---|---|---|---|
0000 | 0 | 1111 | -0 | 0000 |
0001 | 1 | 1110 | -1 | 1111 |
0010 | 2 | 1101 | -2 | 1110 |
0011 | 3 | 1100 | -3 | 1101 |
0100 | 4 | 1011 | -4 | 1100 |
0101 | 5 | 1010 | -5 | 1011 |
0110 | 6 | 1001 | -6 | 1010 |
0111 | 7 | 1000 | -7 | 1001 |
-8 | 1000 |
Now both 0 and -0 are the same thing! How does the maths work out
7 + -3 | ||||
---|---|---|---|---|
7 | 0 | 1 | 1 | 1 |
plus | ||||
-3 | 1 | 1 | 0 | 1 |
equals | ||||
add “units” together (20=1) | 1+1 | |||
10 | ||||
1 | 0 | |||
add “twos” together (21=2) | 1+0+1 | 0 | ||
10 | 0 | |||
1 | 0 | 0 | ||
add “fours” together (22=4) | 1+1+1 | 0 | 0 | |
11 | 0 | 0 | ||
1 | 1 | 0 | 0 | |
add signs together (22=4) | 0+1+1 | 1 | 0 | 0 |
10 | 1 | 0 | 0 | |
0 | 1 | 0 | 0 | |
The carry here sets a flag | 0 | 1 | 0 | 0 |
Sum | 0 | 1 | 0 | 0 |
7 + -3 = 4! Success and no faffing about with the addition.
But remember those overflows, we know it is possible to add two numbers together and end up with a results that is too big to be stored. If we add 7+1 (or any positive number) the result cannot be stored in 4 bits. Similarly if we add -7 + any negative number the result cannot be stored correctly. Is there a way to detect this? Yes, and its very simple - there is a carry in to the sign bit and a carry out from the sign bit then the number has over or under flowed.
- Previous
- Next