为什么8bit限制是-128到127而不是-127到128
因为在二进制补码表示法中,较高位(即最左边的位)用来表示符号位,0表示正数,1表示负数。因此,对于8位二进制数,较高位只能是0或1,而不能是2。如果将较高位作为数字位,则可以表示的数字范围为0~255(无符号),而不是-128~127(有符号)。

一、原因
8位二进制按照补码表示有符号数的范围如下:
11111111 …. 10000001 10000000 01111111 … 00000000
-1 …. -127 -128 127 0
1) 较高位(最左面一位)是0的都是非负数(0也是非负数),较高位是1的都是负数。
2)在较高位变化的时候出现了一个大的“断层”。
这两点其实很有用,因为以较高位的变化为一个“断点”,可以让计算机判断出有符号数运算时溢出(造成小于-128或者大于127的运算)的出现。
我们都知道,补码的其中一个用处就是可以用加法来算减法。
比如:
3 + 8 = 00000011(B) + 00001000(B) = 00001011(B) = 11
3 – 8 = 3 + (-8) = 00000011(B) + 11111000(B) = 11111011(B) = -5
-128 + 1 = 10000000(B) + 00000001(B) = 10000001(B) = -127
-128 + 127 = 10000000(B) + 01111111(B) = 11111111(B) = -1
这些计算都在-128 ~ 127的范围内,如果我们故意产生溢出,算一个小于-128或者大于127的运算呢?
比如,
-128 – 1 = -128 + (-1) = 10000000(B) + 11111111(B) = 01111111 = 127
注意此时较高位都是1,是因为两个1相加越界变成0的,这就是有符号运算的溢出,可以被探测出来。
再比如:
127 + 1 = 01111111(B) + 00000001(B) = 10000000(B) = -128
符号位因为下面的进位被迫变成了1,这也是有符号运算的溢出。
所以符号位的0/1变化,可以被作为有符号运算溢出的一个标志。通过溢出或进位的形式而改变较高位时,可以断定有符号的溢出出现了。
而如果我们将10000000定义为正128,再来看一下128运算(注意下面两个运算基于10000000是正128这个假定):
A) 128 + 1 = 10000000(B) + 00000001(B) = 10000001(B) = -127
B) 128 – 1 = 128 + (-1) = 10000000(B) + 11111111(B) = 01111111(B) = 127
算式A)出现了溢出的现象,但是从计算机底层的二进制运算上看似乎显得“平静如水”,不像上面那样有较高位的进位或溢出变化。而算式B)虽然造成了较高为的溢出而使得较高位从1变成0,但是这却是一个合理的运算。这对于计算机来说就显得很“蹩脚”。
延伸阅读
为什么要用补码
在计算机中,数值一律用二进制的补码来存储。二进制的较高位是符号位,0表示正数,1表示负数。正数的值是其本身,负数的值是较高位(符号位)不变,其它位逐位取反,再加1。这种表示方法有以下优点:
- 可以将符号位和数值域统一处理,无需增加额外的判断和处理逻辑。
- 可以将加法和减法统一处理,无需增加额外的判断和处理逻辑。
- 可以将溢出的情况统一处理,无需增加额外的判断和处理逻辑。