实数可以分为正数、负数,还可以分为整数、小数。计算机中的数据全是0和1组成的二进制数,没有正负号,也没有小数点。那么计算机如何存储负数和小数呢?
因为整数比小数好处理,所以本文先介绍整数,下篇文章介绍小数。
正整数比较好存储,用计算机中0和1组成的二进制数直接存储即可。但是负数怎么办?
因为计算机中只有0和1,没有负号,我们只好规定最高位为0代表正数、1代表负数,其他位代表数值。这种表达方式被称作原码。
但是用原码计算,涉及负数会出错,例如1+(-1)
:
0000 0001
1000 0001
---------
1000 0010
结果为-2。结果明显是错的。
我们用另外一种形式表示-1:
-1 = 0000 0000 - 0000 0001
= 1111 1111
再来计算一下正数与负数的加法:
0000 0001
1111 1111
---------
0000 0000
结果为0,计算正确。这种表示负数的方式叫做补码。正数的补码与原码相同,负数的补码可以用0减去对应的正数计算。
根据前面的内容可知,补码可以参与到正常的加法规则,并且能得到正确的结果:
计算机中的减法其实是转换成加法的:
那么乘法呢?
实验结果是可以的,或者说大多数情况可以,因为32位乘法结果应该是64位,如果结果不超过32位,就是正确的。
真的神奇,我们为加减法设计出来的补码,竟然还能按照原来的规则正确参与乘法运算。
除法呢?
看来除法的结果是错的了,cpu必须为补码单独设计计算规则了。
cpu乘除法具体的计算过程太过复杂,我们仅简单提一下原理。详情参见《计算机组成原理》。
可以类比我们手工在草纸上计算乘法的过程,最低位先乘,高一位再乘的结果需要左移一位。其实计算乘法的过程就是查乘法表、移位、加法。
因为计算机中只有1和0,查乘法表过程可以省略,所以乘法器就是将乘法转换成移位和加法的过程。
除法同理,除法器将除法转换成了移位和减法。