计算机内部是采用二补数(2的补码)表示负数。
减法与加法相比,是不一样的机制。加法只有向前进位,减法则有可能会向前借位,同时,前一位又可能再向前借位,十分麻烦。但我们知道减一个正数就等于加一个负数,于是就需要这个负数容易表示并且符合运算规律,就有了是减法变加法基于补码的运算方式。
对于【负数是先求二进制数,再取反,即1变成0,0变1,最后加1就是补码了】
举个例子:(这是《code》里的例子)
253 – 176 即 1111 1101 – 1011 0000
这个减法运算在个位的时候,就需要向前借位了,换个思路
这是一个三位数,三位数的最大值是999,先用
999 – 176 = 823 同理 用8位二进制数中的最大值减去减数 即 1111 1111 – 【 1011 0000 】 = 【 0100 1111 】
然后,用被减数253加上上面求出来的这个值823
253 + 823 = 1076 同理 1111 1101 + 0100 1111 = 1 0100 1100
然后把这个值加1再减去1000,这样就得到了77
1076 + 1 - 1000 = 77 同理 把上述结果加一再减去9位二进制数的最小值1 0000 0000。
1 0100 1100 + 1 = 1 0100 1101
1 0100 1101 – 1 0000 0000 = 0100 1101
经过观察【 0100 1111 】 就是对 【 1011 0000 】的取反 也就是对减数176取反。
最后一步,
1 0100 1101 – 1 0000 0000 = 0100 1101 就是把1去掉就可以了。
也就是 176 = 1011 0000 取反为 0100 1111 加 1 为 0101 0000(176的补码) 最后加上 253(1111 1101)
01010000 + 1111 1101 = 0100 1101 (这样就只用取反和做加法运算了)
999 – 176 + 253 + 1 - 1000,即253 + (999 – 176) + 1 – 1000,即 253 - 176 + 999 + 1 - 1000 即 253 - 176 。
也就是说
假设2个数为 X,Y
Y的2的补码等于(11111111-Y)+1。所以,X加上Y的2的补码,就等于:
X + (11111111-Y) + 1 假设 等于 Z
Z = X + (11111111-Y) + 1式子可以写为Z = X - Y + 100000000,这在硬件上可以理解为两部分电路来实现,第一部分是前面的X - Y(这里姑且不管计算的结果是正还是负),第二部分是X - Y计算的结果再和100000000相加,最终得到计算的结果Z, 而在8位的计算机上100000000是不能出现的,其实这时100000000就相当于00000000(舍去了最高位)即
Z = X + (11111111 - Y) + 1
= X - Y + 100000000
= X - Y + 00000000
= X - Y