首先从计算机中数值数据的编码和表示说起
机器数和真值
实际运算中,数是有正负的,计算机中的数也有正负,通过用一个数的最高位表示符号,如果字长为8位,分别为D7-D0,那么D7就是符号位,0表示正数,1表示负数,D6-D0为数值位;
例如:
11010111 = -87
机器数:在计算机中,连同符号一起数码化的数,就被称为机器数;如上面的11010111;
真值:使用正负号加其绝对值的表示方法的数值;如-87
原码
将最高位作为符号位(0表示正,1表示负),其它数字位代表数值本身的绝对值的数字;如:数字6在计算机中原码表示为: 00000110数字 -6 在计算机中原码表示为: 10000110注意:
以上是在8位计算机中的原码表示,如果在32位或16位计算机中,表示方法是一样的,只是多了几个0而已.
但是原码也是有缺陷的
有了数值的表示方法就可以对数进行算数运算,但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候会出现问题,如下:
1 - 1 = 1 + (-1) = 0
00000001 + 10000001 = 10000010 (-2)
显然是错误的.
这时候有人提出了反码
反码:
反码表示规则为:如果是正数,则表示方法和原码一样,如果是负数,则保留符号位1,然后将这个数字的原码按照每位取反,则得到这个数的反码表示形式;
如:数字6在计算机中反码就是他的原码:0000 0110
数字(-6)在计算机中反码为: 1111 1001
上文说到了原码的缺陷,在进行减法运算时所得结果与实际结果不相同;
那么反码就解决了减法运算计算的错误,不过还是存在缺陷,如下:
1 - 1 = 1 + (-1) = 0
0000 0001 + 1111 1110 = 1111 1111(-0);有问题
再看看其他减法是否出错:
1 - 2 = 1 + (-2) = (-1);
0000 0001 + 1111 1101 = 1111 1110(-1);正确
说明反码在进行减法运算时是正确的,只有在结果为0时可能带有负号;
为什么会出现这样的问题呢?因为反码的表示范围为(-127-(-0)-0-127),总共256个;
这个问题如何解决?这时候补码出来了!
补码
补码是计算机表示数据的一般方式(这句话很重要,圈起来,要考),其规则为:如果是正数,则表示方法和原码一样,如果是负数,则将数字的反码加上1(相当于将原码数值按位取反然后在对地位加1);
负数的补码就是对反码加一,而正数不变,正数的原码反码补码都是一样的;
再来检验一下上面的问题:
1 - 1 = 1 + (-1) = 0;
0000 0001 + 1111 1111 = 0000 0000;(正确)
那为什么补码可以这样运算而其他的不行呢,
在补码中,用(-128)代替了(-0),所以补码的表示范围变成了(-128- 0-127),共256个;
补码的设计目的
-使符号位能与有效值部分一起参加运算,从而简化运算规则
-使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计
这也就是为什么补码是计算机数据的一般表示方法的原因之一!