说说“补码”
一般教材在介绍有符号数在计算机中的表示方式时,都会从原码、反码开始讲,最后得出计算机里有符号数采用补码表示,而求一个负数补码的常用方法就是原码取反,得反码再加1。所以这几个概念之间有一定的联系。
(说明: 非负数的原码、反码、补码相同)
这里不赘述他们的数学含义,只说采用补码表示有什么好处。
一、解决+0与-0表示的二义性
在数学上+0与-0表示同一个数值,但是如果用原码或反码,在计算机里+/-0对应的都是两个不同的01串,以8位为例:
原码+0:0000 0000 原码-0: 1000 0000
反码+0 : 0000 0000 反码-0: 1111 1111
计算机里是不允许(或者说尽量避免)二义性存在的,所以原码表示和反码表示就被淘汰了,那怎么表示有符号数呢?
聪明的前人想到了补码表示法(它的数学含义及定义这里不赘述了),这里只说求补码的方法:非负数的补码=其原码=其反码,负数的补码按位取反加1,仍以8位为例:

从表中看到,补码表示做到了一一对应,n位二进数数的有符号数表示范围-2^(n-1) ~~+2^(n-1)-1,+/-0的补码表示是唯一的:全0。
这里要强调几点:有符号数的最大值为+2^(n-1)-1,形式为0111……11;
有符号数的最小值是-2^(n-1),形式为1000……00;
-1在任意字长的系统里都输全1。
二、采用补码表示,可以简化计算机中运算器设计
采用补码表示后,计算机中底层硬件进行的是二进制加法运算,根本不区别是有符号数还是无符号数,既可以被解释成有符号数(下图右边),也可以被解释成无符号数(下图左边),为了方便,以4位为例:

采用补码表示,计算机不需要实现单独的减法器,和数学上减一个数等于加上该数的负数相一致。
三、方便数据类型扩展
学计算机的都知道数据类型,也就是数据的字节宽度,大多数语言是允许有默认类型转换的,即不同数据类型之间的数据可以进行转换(一般小字节宽度可以扩展为大字节宽度),然后运算、存储等,采用补码表示就很容易进行数据宽度扩展,补码是针对有符号数的,在进行类型转换扩展时,只要进行符号位扩展,数值本身不变,例如全1在任何机器字长下表示的有符号的都是-1,再举个例子,一个字节的-7表示为:1111 1001,把该数据扩展为两个字节,只要符号位1扩展为:1111 1111 1111 1001即可,补码表示对给数据类型转换带来了很大便利。