We've looked at the history of computing hardware up until the 1980s. Although there was (and is) a fair bit of variety in hardware design, by the 1980s design had converged on two aspects of data representation:
Various hardware has been used to record this state of on or off: [magnetic core memory], and flip-flops, for example. The ideal requirements of such memory are:
For the discussion below b1 and b2 are bits (meaning binary digits), circuits that can be either on or off. We'll arbitrarily decide that 1 represents on and zero represents off. Consider some other circuits (called gates) that take b1 and b2 as inputs, and produce a new output. The behaviour of these circuits is modelled on ideas from logic.
b1 | b2 | output |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
b1 | b2 | output |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
b1 | output |
0 | 1 |
1 | 0 |
There are many other logical operations, for example NAND, where b1 NAND b2 is NOT (b1 AND b2), and NOR, where b1 NOR b2 is NOT (b1 OR b2). However, it can be shown (in later CSC courses) that AND, OR, and NOT are complete, in the following sense. Take any sequence of bits, b1, b2, ..., bn. Dream up an output function of those n bits, in other words, for each configuration of states 0 and 1 of the bits, think of an output state that is either 0 or 1. Then there is an expression involving ANDs, ORs and NOTs that gives the same output as your function.
Here's an example:
b1 | b2 | b3 | output |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 0 |
1 | 1 | 1 | 1 |
Here's an expression that gives the same output: ((NOT b1) AND (NOT b2) AND b3) OR ((NOT b1) AND b2 AND (NOT b3)) OR (b1 AND (NOT b2) AND (NOT b3)) OR (b1 AND b2 AND b3). It looks complicated, but if you trace it carefully, you'll see that it gives exactly the same output as the table. The consequence of this is that any function of n bits can be constructed out of components that implement AND, OR, and NOT. Indeed, you can show that the only component you need is NAND!
In our familiar base 10 number system we use the ten digits 0--9, plus position, to represent any non-negative integer. For example the number 8253 means (8*1000) + (2*100) + (5*10) + (3*1). The right-most digit tells us how many units (ones), the next tells us how many tens, the next how many hundreds, and so on. The rule is that as you move left one position, the magnitude increases by a factor of ten.
Imagine that each of us was born with just one finger (between both hands!). The only choice we'd have is digit up (perhaps 1), and digit down (0 then). If we dreamed up a positional number system under those conditions, we would use the two digits 0--1, and position to represent any non-negative integer. To imitate the base 10 approach, the right-most digit would tell us how many ones, the next digit would tell us how many twos, the next digit how many four, the next digit how many eights, and so on. The rule is that the magnitude increases by a factor of 2 as you move left. Using this rule, work out the value of the following 8-bit number, and express it in base 10 (your usual numbers):
10100110
With a little practice you should be able to convert from base two (binary) to base ten (decimal) systematically. How about the other direction? Here's an algorithm for finding the binary representation of a non-negative integer n:
Try this approach on n=19. You might want to consider why this algorithm works.
Try converting some more positive integers from decimal into binary representation, until you're comfortable with the technique. How should you check you have the correct result?