数据结构之----原码、反码、补码
什么是原码?
原码:我们将数字的二进制表示的最高位视为符号位,其中 0 表示正数,1 表示负数,其余位表示数字
的值。
什么是反码?
反码:正数的反码与其原码相同,负数的反码是对其原码除符号位外的所有位取反。
什么是补码?
补码:正数的补码与其原码相同,负数的补码是在其反码的基础上加 1 。
下图是原码、反码和补码之间的转换方法。
为什么要使用原码?
众所周知,计算机所能读懂的语言是二进制编码,而二进制编码就是我们这里所说的原码。
为什么要使用反码?
原码虽然说很直观,但是它也会存在一些局限性。如,负数的原码是不能直接的用于运算的。
例:1+(-2),得到的结果是 -3 并不是 -1,这明显是错误的。
所以,为了解决这类问题,计算机引入了反码。如果说我们先将原码转为反码,在计算完1+(-2)后,再将结果转换为原码,那么得出的就是正确的结果 -1。
为什么要使用补码?
在原码中,我们都知道数字零有两种表达方式+0 和 −0 ,但是这意味着0是两个不同的二进制编码,它可能会带来歧义。如在判断条件中,如果没有正确区分 +0和- 0,就会导致判断错误。
而如果需要正确的对0进行区分就要进行额外的操作,但是这种操作可能会降低计算机的效率。
并且反码和原码一样,也会存在这个问题,所以为了解决这个问题,计算机引入了补码。
下面是负零的原码、反码、补码的转换过程:
转换原理是在反码的基础上加一,而加一这个操作会产生进位,但是byte类型的长度只有8bite,所以溢出的第九位的 1会被舍弃。
也就是说 负零的补码为 0000 0000 ,与正零的补码相同。这意味着在补码表示中只存在一个零,
正负零歧义从而得到解决。
为什么byte的取值区间为[-128,+127]?
我们注意到,区间 [−127, +127] 内的所有整数都有对应的原码、反码和补码,并且原码和补码之间是可以互相转换的。然而,补码 1000 0000 是一个例外,它并没有对应的原码。
根据上面提到的转换方法我们可以算出 1000 0000的原码是 0000 0000。
这显然是不对的,因为该原码表示数字 0 ,它的补码应该是自身 0。
所以计算机将这个特殊的补码 1000 0000 代表 -128
实际上,(−1) + (−127) 在补码下的计算结果就是 −128 。