19

Why the range of signed character is -128 to 127 but not -127 to 128 ?

msc
  • 30,333
  • 19
  • 96
  • 184
Parikshita
  • 1,301
  • 4
  • 14
  • 22
  • 6
    See [Two's Complement](http://en.wikipedia.org/wiki/Two's_complement). – James McNellis Oct 10 '10 at 01:58
  • Possible duplicate of [Why does the range of int has a minus 1?](https://stackoverflow.com/questions/19333581/why-does-the-range-of-int-has-a-minus-1) – phuclv Dec 29 '17 at 03:38
  • [Why is the range of signed byte is from -128 to 127 (2's complement) and not from -127 to 127?](https://stackoverflow.com/q/11433789/995714) – phuclv Dec 29 '17 at 03:39
  • Possible duplicate of [Why is the range of signed byte is from -128 to 127 (2's complement) and not from -127 to 127?](https://stackoverflow.com/questions/11433789/why-is-the-range-of-signed-byte-is-from-128-to-127-2s-complement-and-not-fro) – Ragnis Dec 29 '17 at 19:45

6 Answers6

29

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.

Chris Jester-Young
  • 206,112
  • 44
  • 370
  • 418
  • @Chris Jester-Young So there were 2 zeros in 1's complement encoding i.e one +0 & one -0 ? – Parikshita Oct 10 '10 at 02:03
  • @Chris Jester-Young And one more thing..is it required to have equal no. of +ve & -ve numbers in the range ? & why ? – Parikshita Oct 10 '10 at 02:06
  • Well, in both two's complement and ones' complement, the top bit specifies signedness. Take away the top bit, and you'll notice that there are 7 bits available for positive values, and 7 bits available for negative values. – Chris Jester-Young Oct 10 '10 at 02:19
  • 1
    Another not often spoken of benefit is that in 2's compliment notation, beyond detecting sign overflow, there is no additional work to handle signed versus unsigned arithmetic. – Guvante Oct 10 '10 at 05:04
  • 1
    It should also be mentioned that the C standard supports implementations using 2's complement, 1's complement, and sign-magnitude. – ninjalj Oct 10 '10 at 21:23
14

In 8-bit 2's complement encoding numbers -128 and +128 have the same representation: 10000000. So, the designer of the hardware is presented with an obvious dilemma: how to interpret bit-pattern 10000000. Formally, it will work either way. If they decide to interpret it as +128, the resultant range will be -127..+128. If they decide to interpret it as -128, the resultant range will be -128..+127.

In actual real-life 2's complement representation the latter approach is chosen because it satisfies the following nice convention: all bit-patterns with 1 in higher-order bit represent negative numbers.

It is worth noting though, that language specification does not require 2's-complement implementations to treat the 100...0 bit pattern as a valid value in any signed integer type. E.g. implementations are allowed to restrict 8-bit signed char to -127..+127 range and regard 10000000 as an invalid bit combination (trap representation).

AnT
  • 291,388
  • 39
  • 487
  • 734
7

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
Yanick Rochon
  • 45,203
  • 21
  • 112
  • 182
  • You do realize that in two's complement that the first bit is not simply a sign bit, right? If it were, you'd have -127 to -0 as valid values (because you could have negative 0 if it were a sign bit) – Mark Elliot Oct 10 '10 at 02:21
  • @Mark, yes, I know. However I tried to stick to the question's boundaries. And in most practical implementations (C, Java, etc.) there is no negative 0. You do raise a valid point though. – Yanick Rochon Oct 10 '10 at 03:52
  • 1
    The "leftmost" bit is actually the *most* significant bit. – mipadi Oct 10 '10 at 04:18
3
#include <limits.h>
#include <stdio.h>
...

printf("range of signed character is %i ... %i", CHAR_MIN, CHAR_MAX );
user411313
  • 3,640
  • 16
  • 16
1

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.

R.. GitHub STOP HELPING ICE
  • 195,354
  • 31
  • 331
  • 669
1

If you look at ranges of chars and ints there seems to be one extra number on the negative side. This is because a negative number is always stored as 2’s compliment of its binary. For example, let us see how -128 is stored. Firstly, binary of 128 is calculated (10000000), then its 1’s compliment is obtained (01111111). A 1’s compliment is obtained by changing all 0s to 1s and 1s to 0s. Finally, 2’s compliment of this number, i.e. 10000000, gets stored. A 2’s compliment is obtained by adding 1 to the 1’s compliment. Thus, for -128, 10000000 gets stored. This is an 8-bit number and it can be easily accommodated in a char. As against this, +128 cannot be stored in a char because its binary 010000000 (left-most 0 is for positive sign) is a 9-bit number. However +127 can be stored as its binary 01111111 turns out to be a 8-bit number.