对于补码的理解

CPU对于数的减法计算,是转换为加法运算的,例如  2 – 3 = 2 + (-3)。

在计算机内部,这些数字是通过二进制表示的,计算机对于正数二进制表示很直接,将对应的数直接转换为二进制即可;对于负数,是将其的二进制转换为补码进行表示(最高位为符号位:1);运算结果也是补码。正数的补码和反码都为自身。

但是为何这样定义补码之后,就可以通过二进制加法得到正确的结果呢?

下面来看下:

对于两个数a,b,其中 a != 0,a+b = 0;那么可以推得b和a互为相反数,即b = -a。

在二进制加法中,考虑到加法会溢出的情况,当 a + b = 0 时,^a + 1 = b(即a取反加1等于b), 同样 ^b + 1 = a。当a>0时,b < 0,此时b的二进制表示,即为 -a 的补码。

例如8bit的加法器,超过8bit就可以溢出, a = 01001000  (十进制72),^a + 1 = 10111000 = b = -a (-72的补码)。

可以看到,补码定义其实就是这样来的:

由于CPU仅支持加法器,当a > 0时,那么-a如何表示呢,根据a + (-a) = 0推得-a的二进制,将这种表示定义为 -a 的补码。

至此,计算机内部对于数的二进制表示有了这样的定义:正数直接表示,负数用补码表示。为了统一,规定正数的补码就是它本身,负数的补码就是除符号位之外的位取反加一。

对于有符号数,最高位为0的数是0或者正数,转换为人们可以理解的数字,按二进制转十进制即可;最高位为0的数是负数,转换为人们可以理解的数字,需要通过补码的定义进行变换,取反加1后,得到实际的数字。

通过这样的定义,发现CPU可以简单的用加法计算就行,不用关心实际细节,其他逻辑再根据数的二进制表示进行转换即可。

不知这样理解是否到位,还请各路大神指正!

点赞