源码反码补码及其相互转换

源码、反码、补码都是针对二进制数而言的
以一个字节(8bit)举例:
源码: 字节的最高位是符号位,符号位为0表示这个数是正数,为1表示负数。其余的7位来表示这个数的绝对值。例如说十进制的+2表示为 00000010,-2表示为 10000010 。
反码: 对于正数来说,反码和源码相等;负数的反码是它的源码除了符号位其余各个位按位取反。例如+2的反码为 00000010 ,-2的反码为 11111101 。
补码: 对于正数来说,反码也和源码相等;负数的补码是它对应的反码+1。例如+2的补码为 00000010,补码为 11111101 + 1 = 11111110 。
如果已知一个数的补码,求源码的方式为:若最高位为0则说明是正数,补码即为源码;为1则说明是负数,将所有位取反后+1,再加个符号得到该值。
对于正数来说,源码反码补码都是一样的,所以反码和补码都是针对负数而言的。在计算机系统中,数值一律用补码来表示和存储。原因在于使用补码,CPU中的加法器可以同时实现加法和减法。如果用源码的话,1 + (-1)= 00000001 + 10000001 = 10000010 = -2;如果用反码的话,1 + (-1)= 00000001 + 11111110 = 11111111,11111111也是反码,其源码为 10000000 = -0,而反码 00000000 表示+0,这样一个0就存在了两种表示方式是不合理的。如果用补码的话,1 + (-1)= 00000001 + 11111111 = 00000000 (只有8位所以最高位的进位舍掉了)

补码的深入讨论:
为什么使用补码就可以把加法和减法统一处理呢?首先思考一个生活中常见的场景:钟表。比如说现在的时刻是6点,如果想调到4点,既可以顺时针转10个小时,又可以逆时针转2个小时。这里的顺时针可以理解为加法,逆时针可以理解为减法,减去一个数可以用加上一个数代替,因为钟表是周而复始的。钟表的模型和计算机的模型是一致的,一个8位2进制数最大为 11111111(10进制255),11111111 + 1 = 00000000 (高位的进位溢出了),所以这个模型是从 0~255 周而复始的循环。举个和钟表相似的例子: 127 - 1 = 127 + 255 = 126
这个模型由于有8位,所以最多能表示256个不同的数,256称为这个模型的模,而-1和255称为同余。可以发现,同余的两个数绝对值加起来正好等于模。再细心一点就会发现,-1的补码为 11111111,如果看成无符号的八位二进制数则正好等于10进制的255。这样一来,负数的补码可以看成负数的同余数,用补码可以将减法加法相同处理的原因就很显然了。

猜你喜欢

转载自blog.csdn.net/weixin_44965650/article/details/106643010