原码、反码和补码

作者:jicanmeng

时间:2014年10月26日


在计算机内部,所有信息都是用二进制的形式表示的,整数自然也不例外。

整数分为正整数,零和负整数。正整数在计算机中的表示我们使用二进制很容易推算出来,例如对于正整数8,二进制的形式是1000。零的二进制形式就是0000。那负整数在计算机中如何使用二进制表示呢?

负整数在计算机中有三种表示方法:原码(sign-and-magnitude),反码(one's complement),补码(two's complement)对于一个正整数来说,原码,反码和补码是相同的。下面会分别说明这三种表示方法,为了方便,假定使用4位二进制数表示一个整数。

第一种方法:原码

最高位表示符号,1表示负数,0表示正数。例如1011表示-3,0011表示3。所以4位二进制数表示的有符号数的范围是[-7,7]。这种表示方法有两个缺点:

  1. 正负相加不为0。例如-1为1001,+1为0001,相加后为1010,表示-2。
  2. 有两个0:+0和-0。

这种方法被直接比较于常用的符号表示法(放置一个“+”或者“−”在数字的数值之前)。一些早期的二进制电脑(例如IBM 7090)使用这种表示法,也许是由于它与通用用途的自然联系。在现代计算机中,这种表示方法已经不再使用。

第二种方法:反码

仍然使用最高位表示符号,1表示负数,0表示正数。其它位和原码的对应是相反的。这就解决了上面提到的第一个问题,但是仍然有两个0存在。

反码这种数字表示系统通常出现在老式的计算机中;PDP-1,CDC 160A,UNIVAC 1100/2200系列以及其它的一些电脑都使用反码算术。和原码一样,反码这种表示方法也在现在计算机中不再使用了。

第三种方法:补码

仍然使用最高位表示符号,1表示负数,0表示正数。其它位在反码的基础上加1。这就解决了上面提到的两个问题。

现代计算机中,有符号数的表示方法都使用了补码这种表示方法

参考资料

  1. C语言点滴 第三章 数据类型
    http://www.hrbxinzhi.com/cbook/03.htm
  2. 关于2的补码:
    http://www.ruanyifeng.com/blog/2009/08/twos_complement.html
  3. 有符号数处理:
    http://zh.wikipedia.org/zh-cn/%E6%9C%89%E7%AC%A6%E8%99%9F%E6%95%B8%E8%99%95%E7%90%86