一、相关概念
1.1 机器数与真值
·机器数 计算机中存储的数据都是带符号的二进制数,例如:5 → 0000 0101 , -5 → 1000 0101 此类数值称之为机器数。
·真值 为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。如:1000 0101的形式值为133,但它实际表示的值为-5,-5称之为真值。
1.2 原、反、补码
·原码 符号位加上真值的绝对值。如+5和-5的原码分别为:0000 0101和1000 0101
·反码 正数的反码是它本身,负数的反码是将它原码的符号位不变,其余各位按位取反。 如+5和-5的反码分别为:0000 0101和1111 1010
·补码 正数的补码是它本身,负数的补码是将它原码的符号位不变,其余各位按位取反再加1(其实就是反码+1)。如+5和-5分补码分别为:0000 0101和1111 1011
二、为何要用原、反、补码
2.1 符号位的问题
我们已知正数的原、反、补码都是相同的,但对于负数来说确是完全不同。在处理加减乘除等运算时,若是人脑来进行,我们可以将符号位抽象出来然后直接操作真值即可。但若交由计算机完成,若还需提前去识别符号位,则会大大增加计算机基础电路的复杂度,故需要考虑带着符号位进行计算。
考虑一个1-1的问题:
·原码计算:1-1 = 1+(-1)= [0000 0001]原 + [1000 0001]原 = [1000 0010]原 =-2 结果显然不对
·反码计算:1-1 = 1+(-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反
= [1000 0000]原 = -0
从结果来看,真值部分是对的,但0前面出现负号是无意义的。反而会引入1000 0000的机器码表示数值0,从而与0000 0000表示的0引起冲突,故而补码码应运而生。
·补码计算:1-1 = 1+(-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]补 + [1111 1111]补
= [0000 0000]补
= [0000 0000]原 = 0
可见,使用补码运算解决了符号位带入的问题和0的符号问题。值得注意的是,在补码的运算结果中,[1000 0000]补 代表的数值为-128,但由于该补码使用的是之前-0的补码,故-128是没有原码和反码表示的。有此也可以引申出,8位二进制值的原码或反码的表示范围为[-127,127],而补码的则为[-128,127]。
2.2 总结
·数字电路的CPU中仅实现了加法器,为实现减法器,减法都是通过转换为加法进行计算的。
·负数在计算机中是以补码的形式存储的,计算过程也是用补码实现的。
三、反码与取反
初学时容易将两个概念混淆,前面已经提到,计算机中数据的存储和计算都是以反码的形式进行的。故取反这一过程也是围绕补码展开的,与反码这一概念并无关系。
看一个+5和-5取反的过程:
+5 = [0000 0101]原 → [0000 0101]补 →按位取反→ [1111 1010]补 → [1000 0110]原 = -6
-5 = [1000 0101]原 → [1111 1011]补 →按位取反→ [0000 0100]补 → [0000 0100]原 = 4
可见,对一个数取反都是先求得该数的补码,对补码进行按位取反,然后对结果再求补码即可。快速计算方法:对数a取反,结果为-(a+1)。
原文地址:https://www.cnblogs.com/jing-wen/p/9128699.html