源码、反码和补码
先来个总结:
1、计算机所有的存储,传输,计算,都是通过补码来的。所以,原码和反码,只存在cpu对输入进行转换到补码的过程中。在计算机世界里,是看不到原码和反码的。它们存在只是因为理论需要它们。
正数:源码、反码和补码,三者一致。
负数:本质上负数在计算机世界里面,它只能用补码表示。而我们常说的负数的源码,反码其实只是针对我们人来说的。
用最简单的8位表示
比如:-1你认为它的源码是1000 0001,但是这只是我们用来计算-1补码的中间结果而已。你把1000 0001给到计算机,它会认为它是补码,会计算肯定不为-1。
所以:
人为规定负数的源码:符号位为最高位 0表示正,1表示负。负数的绝对值表示源码:
|-1| = 1 = 0000 0001,然后设置符号位:1000 0001
负数的反码:符号位不变,其他位取反。得到1111 1110
负数的补码:反码 + 1 = 1111 1110 + 1 = 1111 1111
同样计算机拿到一个二进制串,该如何翻译为十进制呢?比如上面的 1111 1111。计算机发现最高位是1,表示负数。所以它的源码一定不是它本身。需要计算它的补码:
和上面一样,先取反 再加1:
反码:1000 0000
补码:1000 0001
得到:负数(000 0001)= -1
但是有个特列:比如二进制1000 0000,它是存在的,且可以构造的。把它扔给计算机解释,我们根据补码的原则来计算的话,计算得到的结果是0,而计算机得到的结果是-128。
先来说下我们的补码计算的过程:
反码:1111 1111
补码:反码 + 1 = 1111 1111 + 1 = 1 0000 0000
高位溢出扔掉得到:0000 0000
所以,我们计算得到0,但是你不能奢望计算机按照你这个算法来算。当然其他负数都可以按照这么来算,就这个数不能。
查询网上,说1000 0000这种形式的二进制,计算机会特殊处理。那就是说,不会按照正常的补码计算来解释。
1000 0000表示-128是人为规定的
还有一种说法:
首先看最高位,最高位是1,表示这是个负数,已知负数的补码求十进制和正数是有点不同的,第一步,所有位数取反,所以这一步后FFFFFFF1已经变成0000000E,第二步,转换成十进制,E×1=14×1=14,第三步,取倒数再减1,所以(14)倒=-14,-14-1=-15,结果就是这个数-15。
我们按照它的计算规则,重新计算下1000 0000。
它的反码:0111 1111
计算它的十进制:127
取反:-127
再-1 : -127-1 = -128
这样能得到正确的-128。但是最上面:
负数 -> 补码
补码 -> 负数
它们的逆过程,难道不能计算吗?