Here's a interesting question that can be used to judge how much a computer programmer really knows about the machine.

Write out the bit patterns from 0000 to 1111 and ask, "How many different numbers can you get from this.

0000 0100 1000 1100 0001 0101 1001 1101 0010 0110 1010 1110 0011 0111 1011 1111

Here's a list of the answers I've come up with.

The simple binary numbers 0 through 15.

`0000`

0 `1000`

8 `0001`

1 `1001`

9 `0010`

2 `1010`

10 `0011`

3 `1011`

11 `0100`

4 `1100`

12 `0101`

5 `1101`

13 `0110`

6 `1110`

14 `0111`

7 `1111`

15

We get the numbers 7 to -8.

`0000`

0 `1000`

-8 `0001`

1 `1001`

-7 `0010`

2 `1010`

-6 `0011`

3 `1011`

-5 `0100`

4 `1100`

-4 `0101`

5 `1101`

-3 `0110`

6 `1110`

-2 `0111`

7 `1111`

-1

Some of the older computers actually used 1's complement because it was simpler to design some 1's complement circuits. The problem with 1's complement is the existence of negative 0.

The numbers range from 7 to -7 including 0 and -0.

`0000`

0 `1000`

-7 `0001`

1 `1001`

-6 `0010`

2 `1010`

-5 `0011`

3 `1011`

-4 `0100`

4 `1100`

-3 `0101`

5 `1101`

-2 `0110`

6 `1110`

-1 `0111`

7 `1111`

-0

We actually used signed magnitude in our everyday life. It's used for normal decimal integers. We have a sign character, followed by a number of digits of magnitude.

For our bit patterns, signed magnitude gives number from 7 to -7 with 0 and -0. However, we don't use the same bit patterns as 1's complement.

`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

Binary Coded Decimal uses 4 bits to represent a single digit. It was used extensively in financial calculations. Things like updating a billing record where the cost of converting to binary was expensive considering that only a few simple operations needed to be performed with the numbers.

So using BCD we get a single digit, which leaves us with the numbers 0-9 and 6 illegal bit patterns.

`0000`

0 `1000`

8 `0001`

1 `1001`

9 `0010`

2 `1010`

illegal `0011`

3 `1011`

illegal `0100`

4 `1100`

illegal `0101`

5 `1101`

illegal `0110`

6 `1110`

illegal `0111`

7 `1111`

illegal

We can make the first bit a parity bit. Parity is a very simple error checking system. When have even parity, an even number of bits are set to 1. When you have odd parity an odd number of bits are set.

If we use 3 bit unsigned with even parity we get the numbers 0-7 and 8 other bit patterns which contain a parity error.

`0000`

0 `1000`

illegal `0001`

illegal `1001`

1 `0010`

illegal `1010`

2 `0011`

3 `1011`

illegal `0100`

illegal `1100`

4 `0101`

5 `1101`

illegal `0110`

6 `1110`

illegal `0111`

illegal `1111`

7

In Gray code only one bit changes at a time. That makes it very useful for position encoders.

Straight binary is not very good for this job. Think about what would happen if we used straight binary for an encode and positioned the device exactly on the bounder between 7 and 8. Each bit could be on or off depending on the whims of the sensor.

The 4 bit unsigned representation contains an implied binary point just after the last digit. We can move the binary point to the left one and get the numbers 0.0 through 7.5 by 0.5 increments. We can move it to the left two and get 0.0 through 3.75 by 0.25 increments.

`0000`

0 `1000`

4 `0001`

0.5 `1001`

4.5 `0010`

1 `1010`

5 `0011`

1.5 `1011`

5.5 `0100`

2 `1100`

6 `0101`

2.5 `1101`

6.5 `0110`

3 `1110`

7 `0111`

3.5 `1111`

7.5

And with a fixed binary point at the second position:

`0000`

0 `1000`

2 `0001`

0.25 `1001`

2.25 `0010`

0.5 `1010`

2.5 `0011`

0.75 `1011`

2.75 `0100`

1 `1100`

3 `0101`

1.25 `1101`

3.25 `0110`

1.5 `1110`

3.5 `0111`

1.75 `1111`

3.75

We have enough bits for a sign, exponent and fraction. We could make floating point numbers out of our bit patterns. I think it would interesting to try because almost every bit pattern involves a boundary condition. We'll leave that for another day.

Finally we can use a system which assigns the following values to our bit patterns: "0", "1", "83", "47", "a fish", "a horse", "a cow", and "Tuesday". Some of you might look at this and think it's strange. Others may look at and think this author is strange. How do you get such a set of values?

The answer is simple, I made it up. Ultimately the assignment of meaning to bit patterns is up to the programmer. True some common systems like unsigned binary make life a lot easy for him, but ultimately he can choose any assignment he wants to.