3. 十六进制加法
第 0 位:E + C,结果为 26,但是十六进制中没有 26 这个数字,因此需要向左侧的高位进 1,于是第 0 位就剩下 26 - 16 = A。
第 1 位:A + 1 等于 B,再加上进位 1,结果就是 C,十六机制中有这个数字。
四、把负数计算转换成正数计算
1. 原码
原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
例如,用 8 个 bit (8 位二进制数)来表示一个数,+11 的原码为 0000_1011,-11 的原码就是 1000_1011。
2. 把负数计算变成正数计算
我们都知道,CPU 中有加法器,好像从来没有听说过“减法器”。例如计算 5 + 8,转换成二进制来计算:
再来计算一下减法:5 - 8,对于 CPU 来说,只会计算 5 + 8, 但是不会计算 5 - 8。
但是可以转换一下思路,把减法变成加法 5 + (-8),这样不就可以计算了吗?于是计算机先驱者就发明了反码:
正数的反码:保持原码不变;
负数的反码:原码中符号位不变,其余全部取反(-8 的原码是 1000_1000,反码就是:1111_0111);
于是 5 + (-8)的计算过程就是:
此时,就完美解决了减法问题,那么乘法(多加几次)、除法(多减几次)问题也就跟着解决了。至于如何从数学的角度来证明,那就要问那些数学家了!
3. 新问题:如何表示0?
我们现在可以小结一下反码的表示范围(记住:第一位是符号位):
正数的表示范围:0000_0000 ~ 0111_1111,也就是十进制的 +0 ~ +127 这 128 个数;
负数的表示范围:1000_0000 ~ 1111_1111,也就是十进制的 -127 ~ -0 这 128 个数;
有没有发现问题:怎么存在 +0 和 -0 这两个数?而且他们的编码还不一样:+0 对应 0000_0000,-0 对应 1111_1111。
CPU 虽然就是一个傻瓜,让它干啥就干啥,但是 CPU 最不能容忍的就是不确定性!我们都知道 +0 == -0 == 0,它们是同一个数字,但是在二进制编码中,居然有两个编码来表示同一个数。
伟大的计算机先驱者又做了这样一个决定:正数保持不变,负数整体减 1。
也就是说:符号位不变,值整体加1,如下:
这样就成功解决了 -0、+0 的问题!
现在 一个 8 位的二进制就可以表示的范围是:-128 ~ 127,并且中间没有任何重复、遗漏的数字。
既然每一个二进制表示的值发生了变化,那么继续称之为反码就不准确了,此时给它们一个新的称呼:补码,也就是说:上图就变成了这样:
小结一下补码的定义:
正数的补码:保持原码不变;
负数的补码:原码中符号位不变,其余先全部取反,然后再加1(例如:-8 的原码是 1000_1000,补码就是 1111_1000);
此时,我们仅仅是解决了二级制编码的表示问题,那么:补码能直接参与运算吗?运算结果会出现什么问题?