Why the range of signed character is -128 to 127 but not -127 to 128 ?
That is because of the way two's complement encoding works: 0 is treated as a "positive" number (signed bit off), so, therefore, the number of available positive values is reduced by one.
In ones' complement encoding (which is not very common nowadays, but in the olden days, it was), there were separate values for +0 and -0, and so the range for an 8-bit quantity is -127 to +127.
I think an easy way to explain this for the common soul is :
A bit is a value 0
or 1
, or 2 possibilities
A 2-bit holds two combinations or 0
and 1
for four possible values : 00
, 01
, 10
, and 11
.
A 3-bit holds three combinations for a total of eight possible values : 000
to 111
.
Thus n-bits holds n combinations for a total of 2^n possible values. Therefore, an 8-bit value is 2^8 = 256 possible values.
For signed numbers, the most significant bit (the first one reading the value from left to right) is the sign bit; that leaves a possibility of 2^(n-1) possible values. For an 8-bit signed number, this is 2^7 = 128 possible values for each sign. But since the positive sign includes the zero (0 to 127 = 128 different values, and 128 + 128 = 2^8 = 256), the negative sign includes -1 to... -128 for 128 different values also. Where :
10000000 = -128
...
11111111 = -1
00000000 = 0
...
01111111 = 127
In 8-bit 2's complement encoding numbers -128
and +128
have the same representation: 10000000
. So, you have to choose how to interpret bit-pattern 10000000
. If you decide to interpret it as +128
, the resultant range will be -127..+128
. If you decide to interpret it as -128
, the resultant range will be -128..+127
. In actual real life 2's complement notation the latter approach is chosen because it satisfies the following convention: all bit-patterns with 1
in higher-order bit represent negative numbers.
If you just consider twos complement as arithmetic modulo 256, then the cutoff between positive and negative is purely arbitrary. You could just as well have put it at 63/-192, 254/-1, 130/-125, or anywhere else. However, as a standard signed integer format, twos complement came by convention put put the cutoff at 127/-128. This cutoff has one big benefit: the high bit being set corresponds directly to the number being negative.
As for the C language, it leaves the format of signed numbers up to the implementation, but only offers 3 choices of implementation, all of which use a "sign bit": sign/magnitude, ones complement, and twos complement.