为什么8bit限制是-128到127而不是-127到128

Yang 417

因为在二进制补码表示法中,较高位(即最左边的位)用来表示符号位,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。这种表示方法有以下优点:

  • 可以将符号位和数值域统一处理,无需增加额外的判断和处理逻辑。
  • 可以将加法和减法统一处理,无需增加额外的判断和处理逻辑。
  • 可以将溢出的情况统一处理,无需增加额外的判断和处理逻辑。

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部