In this tutorial, we’ll discuss the difference between signed and unsigned variables. We know that almost all computers store data in binary. In a specific language, such as C, Java, or Python, variables can be stored in 8, 16, 32, 64, or 128 bit chunks. Furthermore, we’ve all encountered the terms signed or unsigned. These can be a source of confusion for some programmers, so we’ll methodically understand the differences between them.
2. A Tiny Example
We’ll start with a hypothetical computer that stores variables in 4-bit chunks. Later, we’ll extend this example to more realistic sizes.
Let’s see all the possible values of a 4-bit number:
Since the number of possible values for an n-bit number is , the number of possibilities will be in our tiny example.
If we interpret these values as unsigned, they will range from 0 to , that is, 0 to 15 in our example, where , as shown in the above figure.
3. One’s Complement
We use the leftmost bit as a sign bit in this representation. If this bit is 0, the number is positive and we can find the magnitude of the number by converting the remaining 3 bits from binary to decimal.
For example, 0101 is a positive number with magnitude 5, as shown below:
If we encounter a sign bit , we know the number is negative and can find its magnitude by obtaining the one’s complement, which means inverting each bit in the binary representation. For, example 1011 is a negative number with magnitude , i.e., -4 decimal.
3.1. A Problem With One’s Complement
We notice something sneaky about one’s complement: there are two zeros, a and a .
This is because 0000=0, as we would expect, but at the same time, 1111 is a negative number with one’s complement that represents -0.
This was a serious problem in the early computers (that used one’s complement) as we had to check for both a and a . One’s complement is rarely used in today’s computers, but it is used in some situations, so we have to watch out for this anomaly.
4. Two’s Complement
There is a subtle difference between one’s and two’s complement. To explain this, we present the corresponding figures side by side, so we can conveniently compare the representations.
4.1. Positive Numbers
The sign bit in two’s complement is the leftmost bit, as in the case of one’s complement. We obtain decimal equivalents of positive two’s complement numbers by straight binary to decimal conversion. Thus 0110 equals 6 decimal.
4.2. Negative Numbers
If the sign bit is 1, we obtain the magnitude using two’s complement. The procedure we follow is to take the one’s complement and add 1.
For example, for 1010, we first take the one’s complement . Adding 1 yields , which represents -6 decimal.
4.3. Range of Negative Numbers
In two’s complement, the range of negative numbers is -1 to . In our 4 bit example the range is from -1 to -8.
This range of negative numbers in two’s complement is one greater than in one’s complement and, as we can see from the figures, it eliminates the -1 problem.
5. A Summary of Results
We’ll now summarize our results using a set of tables, one each for unsigned, one’s complement and two’s complement. In each table, we’ll see the specific values for 8, 16 and 32-bit words and also the general expression for the ranges of values. Let’s keep in mind that one’s and two’s complement both have a sign bit at the leftmost end.
5.1. Unsigned Numbers
Unsigned numbers with bits range in value from 0 to . These numbers are all positive–no negative numbers are possible. For example, if , the range of numbers is 0 to .
5.2. One’s Complement Numbers
Let’s have a look at one’s complement. For bits, these numbers range from to -0 and then from +0 t0 .
If we look at the case of , the values range from to -0 and then from +0 to .
As we’ve discussed above, there is a as well as a , which can make things complicated for programmers.
5.3. Two’s Complement Numbers
Finally, we look at the most common signed representation, that is, two’s complement. In this case the numbers range from to 0 and then to . The magnitude of the most negative number is 1 greater than the most positive number, and there is only one zero.
For example, for , the values range from to 0 and then to .
In this article, we’ve presented the concepts of unsigned and signed variables used in computers. We’ve learned that all numbers are represented in binary. A signed number uses a 1 in the leftmost bit position to represent negative numbers.
We’ve also learned that an unsigned variable cannot represent negative numbers, but has a greater range than signed numbers.
One’s complement numbers are symmetric–they have the same magnitude of maximum negative and maximum positive. Unfortunately this leads to a as well as a , which can be a problem for programmers. One’s complement is rarely used in modern computing.
Two’s complement numbers are widely used in today’s computers. The magnitude of the most negative number is 1 greater than the magnitude of the most positive number. There is only one zero.