Numbers and Number Systems

The numbers we use in everyday life are decimal numbers, i.e. they have base ten. What
this means is that when we write numbers down we use ten digits 0,1,2,3,4,5,6,7,8 and 9 to
make up the number. To use numbers larger than ten we need several digits. The value each
digit contributes depends on its position in the written number: The rightmost digit
denotes ones, the digit to the left of that denotes tens, the next one hundreds, the next
thousands and so on, each digit weighing ten times as much as the one to its right. For
example, the number 1243 means it is made of 3 ones, 4 tens, 2 hundreds and 1 thousand
making one thousand two hundred and forty-three altogether.
This may seem very trivial to most of you, but this is mainly because the way we name
numbers is also based on tens. The fact remains that this kind of number system is one of
the greatest inventions of all time. You need only compare it to roman numerals and
imagine doing arithmetic with them to see how useful it is.

Early mechanical computers often used decimal numbers. However, when computers became
electrical (and electronic) it was found to be a nuisance to have components which could
be in ten different positions to signify the ten digits. It was far easier to use
components with only two positions, either off or on. This meant that only two digits (0
and 1) could be used and so it was necessary to use binary numbers instead of decimal
numbers. The fact that Boolean algebra had already been developed nearly a hundred years
before and that this can be used very easily in conjunction with binary numbers must have
speeded up the development of the computer no end.

Binary is based on two instead of ten. This means that there are only two digits 0 and
1, and that in a written number each digit is weighted twice the digit to its right.
Therefore the rightmost digit denotes ones, the digit to its left twos, the next fours,
then eights, sixteens etc. For example, the binary number 10101011 means it is made of a
one, a two, an eight, a thirty-two and a one hundred and twenty eight, making one hundred
and seventy one, or 171 when written in decimal form.

As you can see, it is quite easy to convert binary numbers to decimal. Simply add up
the weights of the non-zero digits in the binary number. Since we are used to working in
decimal, we automatically end up with the right decimal number.

To convert a decimal number to binary, the following method suggests itself. Find the
highest power of two that is less than the given number. This is the weight of the
leftmost non-zero digit in the binary number. Subtract it, and find the next highest power
of two that is smaller, which gives the weight of the next non-zero binary digit. Repeat
this until there is nothing left. For example the number 171. Consider the weights of the
binary digits, two, four, eight, ....., one hundred twenty-eight, two hundred fifty-six.
Clearly one hundred and twenty eight is the largest weight that fits, so we know that the
binary number will be 1xxxxxxx, and the x's are chosen so that they represent the
remainder 171-128=43. The next weight that fits is 32, so we have 101xxxxx with remainder
43-32=11. Continuing this process we end up with 10101011 and remainder 0. The words
'binary digit' are usually shortened to the word 'bit'. Most small computers are
constructed to use numbers with up to eight binary digits, and this is called a byte. A
byte can therefore hold any value between 00000000=0 and 11111111=255. Sometimes we will
wish to talk about one particular bit, and to do this we number them: the rightmost bit
(the ones) is called bit 0, the next bit (the twos) is bit 1, and so on until bit 7 which
has weight one hundred twenty-eight. Bit 0 is also called the least significant bit,
because it has the smallest weight. Similarly, bit 7 is the most significant bit in a
byte.

Two bytes put together are often called a word. A word contains 16 bits, so can hold
any value between 0 and 65535. Again the bits are numbered from bit 0, the least
significant bit, to bit 15, the most significant bit. The two bytes that make up the word
also have their own names; the low byte contains the eight bits 0 to 7 (those of lowest
weight) and the high byte contains bits 8 to 15.

There is another way to convert decimal to binary that is often used. When using
decimal numbers, dividing by 10 is done very easily by removing the final digit and
furthermore that digit gives the remainder of the division. Similarly, division by 2 using
binary is also done by chopping of the last bit, and that bit is the remainder of the
division so it indicates whether the number was odd or even. Using this principle we can
convert 171 a different way: 171 is odd, so the last bit of its binary representation is
1, i.e. it looks like xxxxxxxxx1. Dividing 171 by two (ignoring that remainder of 1) we get
85. Now we know that xxxxxxxxx1 without the final 1 would be 85 as a binary number so we
must convert it to binary and put it to the left of the 1. All we need to do therefore is
repeat this process, like this:

It is cumbersome to work with binary all the time, because
binary numbers are long. This also makes it easier for mistakes to creep in which are
difficult to notice in a mass of 0's and 1's. Decimal numbers on the other hand always
need to be converted to a form that a computer can understand. As a compromise between
these, hexadecimal is used which is based on the number sixteen.

For hexadecimal we therefore need sixteen possible digits.
We only have ten so far, viz. 0123456789, so we need 6 more symbols to represent the
others. The first six typographical symbols that come to mind are of course the letters
ABCDEF. These will now represent the digits ten to fifteen. As you would expect, each
hexadecimal digit is weighted 16 times the digit to its right. Thus the hexadecimal number
AB is made of A sixteens and B ones, in other words ten sixteens and eleven ones, making
171.

The great advantage of using base sixteen is that each
hexadecimal digit can hold exactly the same information as four binary digits. Both can
denote any number between zero and fifteen. This makes converting between binary and
hexadecimal very easy. The digits A and B denote ten and eleven respectively, or 1010 and
1011 in binary. Therefore AB is 10101011 in binary. Bytes can be denoted in hexadecimal by
at most two hexadecimal digits, a word needs at most 4 digits.

There is one more way of representing numbers in a
computer, called binary coded decimal or BCD. In the Psion organiser this is used in
storing long decimal numbers. This is not a mathematical number system like any of those
mentioned before, but merely a method of storing decimals in an easy to use way. It is
unlikely that you will ever need to use this method, but it nevertheless interesting.

To store a large decimal number without converting it to
binary, we could simply store each decimal digit in a separate byte. This is a little
wasteful of memory, because the numbers 0 to 9 use 4 bits at the most, so the 4 bits at
the left of each byte would be zero. In binary coded decimal numbers, two decimal digits
are put in a single byte by using four bits each.

What all this means is that a binary coded decimal number
is very easy to convert to decimal. Simply convert each half byte to a single digit of the
decimal number. This is the same way as a byte is converted to hexadecimal, so this leads
to the slightly confusing situation that when for example the decimal number 42 is stored
in BCD form, what is actually stored is the hexadecimal number 42.

We haven't talked about negative numbers at all yet.
Decimal numbers simply have a minus sign if necessary. This can also be used with binary
or hexadecimal numbers, so for example -AB denotes -171. To store the information in a
computer we need one extra bit to store the sign in. Unfortunately we only have eight or
sixteen bits to work with, so if we allow negative numbers we have only seven or fifteen
bits to hold the size of the number.

Suppose a single byte contains 11111111, and we add 1 to
it. It should then hold 100000000, but since there are only 8 bits in a byte, the left bit
will not be stored, leaving 00000000. In this sense the number 11111111 acts very much
like minus one, because adding one leaves zero.

In so called two's complement binary numbers, this is
exactly how negative numbers are denoted. In an eight bit number bit 7 denotes the sign.
If it is non-zero we have a negative number, otherwise the byte is positive or zero. The
binary numbers 00000000 to 01111111 denote 0 to +127, and the numbers 11111111 down to
10000000 denote -1 to -128.

Suppose we want to write -100 in two's complement form. We
know that +100 is written as 01100100 in binary. Complementing all eight bits, i.e. changing
each 0 to 1 and vice versa, we arrive at 10011011. It is obvious that these two numbers
add to 01100100+10011011=11111111, but we want them to add to 100000000 because this
becomes 0 in an 8-bit number. We therefore need to add one to it, giving
10011011+1=10011100. So -100 is 10011100 in two's complement form.

A word can also be in two's complement form. In this case
it is bit 15 that holds the sign and bits 0 to 14 hold the value. A word can therefore
hold the values -32768 to +32767. Negating numbers works the same way as before, by
complementing each bit and adding one. For example, 100 is written as 0000000001100100 in
binary, so we get 1111111110011011+1=1111111110011100 for the number -100.