前言
今天,我们来思考几个问题:
为什么负数要用补码表示?
十进制小数怎么转成二进制?
计算机是怎么存小数的?
0.1 + 0.2 == 0.3 吗?
…
别看这些问题都看似简单,但是其实还是有点东西的这些问题。
正文
为什么负数要用补码表示?
十进制转换二进制的方法相信大家都熟能生巧了,如果你说你还不知道,我觉得你还是太谦虚,可能你只是忘记了,即使你真的忘记了,不怕,贴心的小林在和你一起回忆一下。
十进制数转二进制采用的是除 2 取余法,比如数字 8 转二进制的过程如下图:

接着,我们看看「整数类型」的数字在计算机的存储方式,这其实很简单,也很直观,就是将十进制的数字转换成二进制即可。
我们以 int
类型的数字作为例子,int 类型是 32
位的,其中最高位是作为「符号标志位」,正数的符号位是 0
,负数的符号位是 1
,剩余的 31 位则表示二进制数据。
那么,对于 int 类型的数字 1 的二进制数表示如下:

而负数就比较特殊了点,负数在计算机中是以「补码」表示的,所谓的补码就是把正数的二进制全部取反再加 1,比如 -1 的二进制是把数字 1 的二进制取反后再加 1,如下图:

不知道你有没有想过,为什么计算机要用补码的方式来表示负数?在回答这个问题前,我们假设不用补码的方式来表示负数,而只是把最高位的符号标志位变为 1 表示负数,如下图过程:

如果采用这种方式来表示负数的二进制的话,试想一下 -2 + 1
的运算过程,如下图:

按道理,-2 + 1 = -1
,但是上面的运算过程中得到结果却是 -3
,所可以发现,这种负数的表示方式是不能用常规的加法来计算了,就需要特殊处理,要先判断数字是否为负数,如果是负数就要把加法操作变成减法操作才可以得到正确对结果。
到这里,我们就可以回答前面提到的「负数为什么要用补码方式来表示」的问题了。
如果负数不是使用补码的方式表示,则在做基本对加减法运算的时候,还需要多一步操作来判断是否为负数,如果为负数,还得把加法反转成减法,或者把减法反转成加法,这就非常不好了,毕竟加减法运算在计算机里是很常使用的,所以为了性能考虑,应该要尽量简化这个运算过程。
而用了补码的表示方式,对于负数的加减法操作,实际上是和正数加减法操作一样的。你可以看到下图,用补码表示的负数在运算 -2 + 1