负数的补码为什么是对其绝对值取反加一
但是为什么是这样呢?
补码之所以存在,是因为计算机不能(或者不方便,待研究)像我们人类那样去做减法,所以通过特定的方式让计算机通过做加法的方式实现减法的效果。这种方式的原理,拿钟表来说明一般会比较容易理解。
比如现在是下午5点,然后我们想知道之前2个小时几点,但钟表又不能倒退,怎么办呢?我们知道,对钟表而言,12个小时是一个循环,12个小时前也是5点,但是是上午五点。
那么2小时前的时间可以这么算:
其实补码的原理类似,还以8位有符号数字为例,想象一个钟表有0~127共128个刻度,它的循环为128:
从以上可以看出,减去x时可以这样算,先回拨一圈(-128),然后再往后走回拨多了的(128 - x)步。
在补码中可以将最高位符号位理解为回拨一圈的标记,比如
然后再看下如何从x迅速求出(128 - x),以2和126为例,当两个数和为127时,是相互取反的关系。
可知,当两个数和为128,是相互取反加1的关系。
最终可知,对2取反加1,分为两个部分:
1)低7位:表示求出回拨多了的部分,也就是(128 - 2) = 126
2)最高位符号位:对符号位取反,符号位变为1,代表着对某个数"回拨一圈",即-128;
取反加一,通常是指:“原码取反加一”。
其实,这是不对的。
求负数的补码,是有公式的:
补码 = 负数 + 2^n, n 是位数。
正数,不存在变换成补码的问题。
--------------------------
为什么是“正数取反加一”?
下面用 4 位二进制数来说明。
假设一个负的二进制数是:X =-xxxx。
其中的 xxxx,就是二进制的绝对值,这就是一个正数。
按公式,[X]补 = -xxxx + 2^4
= -xxxx + 1 0000。
式中的 1 0000,可以写成:1111 + 1。
代入后,[X]补 = 1111-xxxx + 1。
式中的 1111-xxxx:
如果 x 是 0,1-x 就是 1。
如果 x 是 1,1-x 就是 0。
所以,1111-xxxx,就是【对绝对值取反】。
式中的 + 1:
就是在取反之后,再加上 1。
因此, X 的补码就是:【对绝对值取反、加一】。
--------------------------
注意:这里说的取反,只是对负数的绝对值 xxxx 取反。
在这里,既没有用原码,也没有用反码。更没有“符号位不变”。
所以,求补码,与“原码、反码和符号位”没有任何关系。
其实,原码反码符号位,都是无用的。
特别是-128,它根本就没有原码和反码!
只有用“绝对值取反加一”,才能求出-128 的补码。
那么,书上,总是讲“原码反码符号位”,有什么意思呢?
真是怪事。
“补码”,是计算机进行正负数计算时,唯一使用的“代码”。
原码和反码,计算机都是不用的。
其实,所谓的“补码”也是正常的数值,并不是“什么码”。
计算机使用二进制数。 这些二进制数,不存在什么“符号位”。
八位数的范围是:0000 0000 ~ 1111 1111。 这些数,都是正数。
对应十进制数是:0 ~ 255。 计算机专业则称之为:无符号数。
两个八位二进制数相加,和,可能会出现进位。进位值则是:2^8 = 256。
随便找两个二进制数做加法,列出竖式如下:
图中的加法运算,出现了进位(2^8 = 256)。
如果保留进位,和,就是 256 + 26 = 282,运算正确!
如果忽略(舍弃)了进位,就是减去了 256,和,就只剩下 26 了。
那么,加上 255,再减 256,此时的加法,就变成了减法运算!
此时的“无符号数”255,就成为了“有符号数”-1 !
于是,计算机专家就将 255 (1111 1111),称为:-1 的补码。
同理:254,就是-2 的补码;
。。。 。。。
最后,128,就是-128 的补码。
这就是说:255 ~ 128,在舍弃进位之后,它们就等于:-1 ~-128 !
计算机专业教材中,负数补码的公式就是:[ X ]补=2^n+X。
这个公式,正是说明了上述相等关系。
那么,127 还能不能当做负数呢? 不能!
因为,127 (0111 1111) 的最高位是 0。相加后,进位只能是 0。
即使舍弃进位 0,127,也不能表现出负数的特点。
所以,0 ~ 127,这 128 个无符号数,就只能当做它们自己了。
因此,计算机专业教材中正数补码的公式,就是:[ X ]补=X。
-----------------------------
看明白上述介绍,就可以理解:
所谓的“补码”,本来都是正数。 而且,也都属于“无符号数”。
无符号的“补码”,能够当成负数使用,其根源就在于【舍弃进位】。
那么,利用“补码”当做“有符号数”做加减运算,与“无符号数”的加法,算法显然是完全相同的,都是逢二进一!
因此,“有符号数(补码)”、“无符号数”,就可以【共用同一个加法器】!
利用【舍弃进位】,就实现了“两种算法(加减)”的统一、“两种类型数据”的统一。
计算机,只需配置一个加法器,便可横行天下!
-----------------------------
原码和反码,都没有这些功能。
所以,计算机中,就无法使用原码和反码进行计算。甚至,都不保存它们。
老外的算术水平太洼了,弄不清楚进位的事。百般无奈,只好编造了:
“机器数符号位原码反码补码正数三码相同负数取反加一符号位不变模同余符号位也参加运算时针倒拨正拨 ... ”
这些,都是垃圾概念! 你就是把它们都背熟了、会做了,也是啥用都没有的。
当然,你如果当上了计算机老师,你还得拿这些去忽悠下一代学生。