补码究竟是什么?

1 什么是补码
计算机底层均是通过二进制表示数据,原码、反码、补码是计算机中对数字的二进制表示方法。计算机以二进制补码的形式存储整数,最高位是符号位,0 表示正数,1 表示负数,其余位为数字位。

原码:将最高位作为符号位(0 表示正,1 表示负),其它数字位代表数值本身的绝对值的数字表示方式。

反码:如果是正数,则表示方法和原码一样;如果是负数,将其绝对值的原码各位取反,则得到这个数字的反码表示形式。

补码:如果是正数,则表示方法和原码一样;如果是负数,则将其反码加上 1(相当于将原码数值位取反,然后在最低位加 1)。

正数的原码、反码、补码完全一样,只有负数需要按照以上规则计算。

0 的反码、补码都为 0。

在计算机内部使用固定数量的位来表示整数:比如 32 或 64 ,简单起见,我只考虑 8 位。以 8-bit 二进制数表示十进制整数。它的可表示范围包括 - 128 到 127,即总共可以表示 256(2^8)个整数。

如计算 -3 的二进制补码,先计算 3 的原码 0000 0011,取反得到 1111 1100,再加 1 为 1111 1101。

 

2 为什么使用补码
计算机为什么要用补码表示负数,而不是只改变正数的符号位,使用原码表示负数进行计算呢? 用原码表示负数,看起来很简单易懂,但是进行加减等计算时,就会很麻烦。 +3 原码为 0000 0011,-3 原码为 1000 0011,这两个数相加,直观上应该等于 0,但是相加结果为 0000 0011 + 1000 0011 = 1000 0110,2000 0110 不管怎么解释都不会为 0。

使用原码计算时,那么 0 就有两种表示形式:正 0(0000 0000)和负 0(1000 0000),这显然也是我们不愿看到的。

如果计算机内部采用原码来表示数,那么在进行加法和减法运算的时候,需要转化为两个绝对值的加法和减法运算。计算机既要实现加法器,又要实现减法器,代价有点大,那么可不可以只用一种类型的运算器来实现加和减的远算呢?

补码的出现,就是为了解决这个问题的,使得计算机通过使用加法器就可以得到实现符合直觉的结果。

采用补码形式计算 +3-3 =,+3 补码为 0000 0011,-3 补码为 1111 1101,计算过程为 0000 0011 + 1111 1011 = 0000 0000,符合我们的直觉。

3 补码的实现原理


 

将时针从12点顺时针拨2个小时,和顺时针拨14个小时,和逆时针拨10个小时都是指向2,因为时钟一圈是12个小时。

12 + 2 = 14; 12 + 14 = 26; 12 - 10 = 2

也就是说14、26、2在表盘上是相同的表现形式,将它们除以 12,得到相同的余数 2;12小时代表时钟旋转一周,在计算机里类似的概念叫模,它可以实现化减为加,本质上是将溢出的部分舍去而不改变结果。

3.1 无符号二进制数
在计算机中使用 8 位无符号二进制数,可以表示 0 ~ 255 之间的任意数字,一共 256 位数字,表示范围的模为 256。在进行计算时,计算机只会读取低 8 位的数据,就会出现如下情况:1 与 257 的在此计算机看来是表现一样的,因为任何大于 255 的数都不能用 8 位二进制表示,溢出的部分会被舍去。

8 位二进制可以表示 256 个数,把它们围成一个圈,如下图所示:

可以看到 0000 0001 与 1 0000 0001 重叠在相同位置。

3.2 有符号二进制数
在计算机中使用 8 位有符号二进制数,有符号数的表示范围是-128~127。

如前所述,如果使用原码表示整数,那么进行加减运算时,有符号二进制数之间的运算需要制定与无符号二进制数不同的规则,否则得到的结果不符合直觉;但是用补码表示整数,有符号二进制数之间的运算有符号二进制数之间的运算则可以实现与无符号二进制数相同的计算规则。

从 0 开始,往前走 n 步,和往后走 256-n 步,到达的是相同的位置。

无符号数和有符号数的模都是 256,1111 1111 表示无符号数的 255,也可以表示有符号数的 -1。

有了同余这个机制,无论是无符号数还是有符号数,计算机都可以使用相同的规则进行计算,同样的二进制输入,肯定会得到同样的计算结果,把计算结果看作是无符号还是有符号,计算机是不管的,是由我们说了算。而且这种表示方法也解决了 0 有两种表现形式这个问题,0000 0000 表示 0,1000 0000 则为 -128。

比如对于二级制算式 1000 0000 + 0000 0111 = 1000 0111,我们可以看做是无符号数计算 128 + 7 = 135,也可以看做有符号数计算 (-128) + 7 = (-121)。

同样的,二进制算式 0001 0000+1111 1101 = 1 0000 1101,可以看做是无符号数计算 16 + 253 = 13,也可以看做有符号数计算 16 +( -3) = 13。

补码的本质:找到一个替代负数(-3)的正数(253),并用此正数的二进制形式参与运算,进行加法运算后,将得到的结果中溢出的数字舍去后,只读取结果中固定位数(此处是 8 位)的二进制数作为运算的结果。

4 补码的计算方法

正数的补码与原码相等。将最高位作为符号位,其余各位,其它数字位代表数值本身的绝对值。

负数的补码有两种计算方式

先求出该负数绝对值的原码,再全部取反得到该负数的反码,最后加1即得补码。

负数N + 模M = sum,sum对应的无符号二进制数既是该负数的补码。

第一种是根据补码的定义计算,前面已经详细介绍。

第二种是引入模之后获得的计算补码的新方式:比如计算 -3 的二进制数,256 + (-3) = 253,253 的无符号二进制形式为 1111 1101,因此 -3 的补码就是 1111 1101。
————————————————
版权声明:本文为CSDN博主「Jintaowd」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Tian_JT/article/details/128358374

猜你喜欢

转载自blog.csdn.net/modi000/article/details/131393617