Signed numbers in digital world
In real world, it is easy to represent negative numbers as we can prefix a ‘+’ or ‘–’ sign to the number to denote if it is a positive or negative number. However, in digital world, we need to store all numbers as ‘0’ or ‘1’ and hence we need a representation of negative numbers in binary format.
Following methods are commonly used to represent signed number in digital world:
Sign magnitude:
This is the easiest method to represent signed numbers in digital form. If a datatype stores signed number, then MSB (Most Significant Bit) represents the sign of number, and the remaining bits represent the magnitude of number. Usually value ‘0’ for MSB indicates a positive number and value ‘1’ for MSB indicates a negative number. For a signed char datatype, it can be pictorially represented as following:
E.g if we need to store a number in signed char datatype. i.e. 8 bits (1 byte), then
+3 = 000000112
-3 = 100000112
With this representation for signed numbers, the range of a datatype is
- For signed datatype
- Minimum value = -(2n-1 – 1), where n is the size of datatype in bits
- Maximum value = (2n-1 – 1), where n is the size of datatype in bits
- For unsigned datatype
- Minimum value = 0
- Maximum value = (2n – 1) where n is the size of datatype in bits.
Remember that you can know the size of any datatype on your system using sizeof operator. As you can notice, in this representation, integer 0 has two representation – 000000002 and 100000002, which are logically representing +0 and -0. This reduces the range that a datatype can have as integer zero occupies two representations. Additionally it makes the arithmetic operations complex and confusing.
1’s complement
1’s complement of a number is obtained by inverting all its digits. E.g. 1’s complement of 3 (= 000000112) is obtained by replacing binary digit 0’s with 1 and 1’s with 0, i.e. the 1’s complement for integer 3 is 111111002
With this representation, negative counterpart of a number is represented by it’s 1’s complement. Once again, the MSB denotes the sign of number.
+3 = 000000112
-3 = 100000112
Note that in this representation as well, the integer 0 has two representation – 000000002 and 111111112. Hence the problems that exist with Sign magnitude notation, persist in this representation as well. Also the range of numbers represented by a datatype remains the same, though the representation of negative numbers is different.
2’s complement
The most common method to represent negative numbers in digital world is 2’s complement. A negative number is represented as 2’s complement of it’s positive counterpart.
2’s complement of number = 1’s complement of number + 1.
e.g. 2’s complement of 3 = (1’s complement of 3) + 1
= 1’s complement of 000000112 + 1
= 111111002 + 1
= 111111012
With this representation, the negative counterpart of a number is represented by it’s 2’s complement. In this representation as well, the MSB denotes the sign of a number. Hence with 2’s complement representation for signed numbers-
+3 = 000000112
-3 = 111111012
As you can observe that now integer ‘0’ does not have different representation. 2’s complement of 0 (=000000002) too is 000000002
With 2’s complement, since the value ‘0’ for MSB denotes positive number, the maximum value for the datatype remains the same – 2n-1 – 1. However the minimum value represented now is -1*2n-1
e.g. +128 in binary notation is represented as 100000002
Hence with 2’s complement representation:
-128 = 1’s complement of 100000002 + 1
= 011111112+1
= 100000002
As you can observe that though +128 doesn’t fit in 8 bits, -128 very well fits in 8 bits, hence increasing the range of values that an 8 bit datatype can represent to -128 to + 127. This range was -127 to +127 in sign magnitude as well as 1’s complement representation.