补码原理探究

大一的时候学习计算机基础,知道这么一个概念:负数的补码 = 对应的正数的原码取反 + 1。当时是知其然不知其所以然,记住一个公式却不知道怎么来的、为啥这样。最近刷题的时候接触到了补码,就打算探究一下这个东西的原理。


问题:

我们的问题来源是:用二进制表示正数与负数。首先引入一个的概念,可以理解为二进制可以表示的数的范围。比如,4位的二进制,可以表示16个数,这里的模就是16。


一种思路:

我们下面就以4位二进制为例。对于无符号数,0000~1111可以依次表示0~15。不过除了正数,我们还想要表示负数。一个自然的想法就是拿出0000~1111的一半来表示正数,一半表示负数。具体地,可以让最高位作为符号位,0表示正,1表示负。

假如我们不知道补码的存在,我们可能会这样做:既然0001表示1,那么让1001(只改了最高位即符号位)表示-1。以此类推,1010表示-2,...,1111表示-7。这样,0000~1111被分为三部分:0000~0111表示0~7;1001~1111表示-1~-7;0000和1000都能表示0。。

先不说0有两个表示法的问题,就看两个数相加会产生什么结果。求1 + (-1):0001 + 1001 = 1010,这tm不成了-2吗?对,以上面的表示法,是不能直接按二进制运算规则求加减法的,得考虑两个加数的正负号,这就增加了复杂度,是计算机设计者不希望看到的。


补码表示:

我们换一种表示方法:以0000~0111表示0~7(正数表示方法不变),以1000~1111(无符号的8~15)表示-8~-1。具体来说,假设a为正数,那么-a表示为:模-a。这样不仅刚好把16个数都利用起来,还有一些天然的优点(下面介绍)。

我们先来看看“原码取反加1”是怎么来的。设 a = 1 = 0001,模 = 16 = 10000,模 - a = 10000 - 0001 = (1111 + 1) - 0001 = (1111 - 0001) + 1,注意观察,(1111 - 0001)就是对0001各位取反,这就是所谓的“原码取反加1”!

再来看看加减法。求 3 + (-4) :4的补码是1100(16-4=12),则 3 + (-4) = 0011 + 1100 = 1111 = -1的补码。看来,使用补码进行加减,我们不用单独考虑符号位了。上面这是一个特例,我们来看看一般的情况(模还是16):

求a - b,其中a和b都是正数。采用补码运算的时候,a - b = a + (16 - b) = 16 + (a - b) ,如果 a > b,a - b为正,左边的16被舍去了,结果就是 a + b;如果 a < b,a - b为负,16 + (a - b)就是 a - b 的补码表示。

a 与 b 同为正或同为负的情况可以做类似的分析,这里我就不展开了。

所以,有了补码,正数、负数的加减法运算被统一了起来,大大方便了计算机的运算。


猜你喜欢

转载自blog.csdn.net/csdnqixiaoxin/article/details/80955452
今日推荐