彻底理解原码、补码、反码
原码、补码、反码的概念
为了简单起见,我将以一个字节(8bit)来举例说明。
正数:原码、补码、发码都是原码本身。
负数:原码、补码、发码下面分别给出说明以及例子。
原码:最高位表示符号位。最高位为0代表正数,最高位为1代表负数。
原码:最高位表示符号位。最高位为0代表正数,最高位为1代表负数。
反码:除了符号位不变,其他位取反,0变为1,1变为0。
反码:除了符号位不变,其他位取反,0变为1,1变为0。
补码:反码加1。
补码:反码加1。
为什么计算机要用补码来表示数字
当我们在做减法运算时,需要用
正数-正数。
但是当我们做减法运算时有可能遇到减不够而需要借位的情况,这显然比较麻烦的。但是我们将式子转化为
正数+(-正数),
将减法换为加法就简单了许多,只需要考虑进位就可以了。所以我们只需要制定一套用于做加法运算的电路就可以了。(计算机中只有加法器,所以减法就是通过加法来完成的)。
原码表示数字的问题
在上图中我们用一个圈来表示一个子节所能表示的所有数字的原码,图中相连的数字表示相加都为8个1的原码,但是我们用原码表示数字,相加后的原码并不相同。所有我们用原码来表示数字,在正数+(-正数) 所得到的二进制原码相同,但是根据我们的计算得到的数字却不相同。
补码是如何消除原码的问题
如果用反码表示数字在相加的时候我们知道相加结果都为8个1结果的反码也都是相同的。但是
我们观察可以发现0的表示方法有+0和-0两种表示方法。存在多对一,这是不允许的。
反码是如何消除补码的问题
为了解决
0存在的多对一的情况,
所以我们将负数都顺时针旋转1个单位。将-0旋转到+0的位置。这时0就只有唯一的表示方法了。这时我们发现结果都为8个1结果表示的补码也都为-1。解决了多对一的情况。但是我们顺时针旋转后最后一位还空出一个位置,为了与127相加得到-1所以这个空我们填-128就能顺利的得到我们的结果。
所以我们在求负数的补码时常常就是用负数的原码然后原码再取反得到反码,反码再加一就得到了负数的补码。
总结:
在计算机的设计中为了简单,我们只设计了一套加法器,所以在计算减法时,将之转化为
正数+(-正数)
的形式计算。但是在原码表示数字时,在计算过程中我们得到的原码的二进制相同但根据我们的计算得到的答案确实不相同。所以我们引入了反码,反码虽然我们能得到的反码的二进制与我们计算出的答案也是相同的。但是出现了新的问题就是
0有+0和-0,多对一的新问题。
最后我们通过将
负数的反码顺时针旋转一个单位,(反码加1)
得到补码,最后我们能得到的补码的二进制与我们计算出的答案也是相同的。所以我们表示数字时我们用补码就能够满足计算机用一套相同的加法规则计算出正确的结果。
正数的补码就是原码。
负数的补码先计算出原码,然后计算反码,再将反码加1得到补码。
参考视频:
彻底理解原码、反码、补码。