补码起源

补码起源于数学计算中的概念,详见 wiki 。wiki 中对于补码的定义是 For a given number of places half of the possible representations of numbers encode the positive numbers, the other half represents their respective additive inverses. The pairs of mutually additive inverse numbers are called complements.
这里主要说一下其中的基数补码 (radix complement)。基数补码的定义是一个 n 位数的 b 进制数字 y 的基数补码为 。这里还有一个概念是 diminished radix complement (diminished 是降低,减少的意思),它的定义为 , 在原来基础上减一(可以与向高位借一位作类比)。
1) 其中 可以变形为:

2) 举个例子,比如说

3) 再来个更具体的图 二的补码演示

二的补码

1) 咬文嚼字
有了 radix complementdiminished radix complement 的概念后,二的补码中的二自然就是 radix 了,也叫作 two's complement 。那 diminished radix 呢?wiki 中的叫法是 ones' complement。两个叫法中有个微小的差别就是 s 的位置, 第一种补码表示互为补码的数字是基于二进制表示的,而第二种补码很形象的表示出计算补码时 的每一位上都是一。还要提一嘴的是,在书中或讨论中,人们有时会说 one's complement 或 one complement ,其实就是 ones' complement 。我个人更喜欢 ones' complement ,不仅形象而且不易混淆。如果你现在感觉满头雾水, 还有点生气, 我表示很抱歉。或许下面可能就是你要找的东西了。
2) 从 0.9 到 1 实现补码
现在我们有了补码的概念和计算方法,那我们先来试着计算一个数的补码吧。比如计算一下 在 8 个 bit -26 如何表示 。首先 -26 是 通过其补码 26 间接算出来的。直接上图。计算补码
同样的道理,-26 在 8位数 并且 eight's complement , ten's complement 或 sixteen's complement 下表示都可以这么算。示例如下 3) 利用补码进行加减运算
因为减去一个数也可以看作是加上一个负数,所以我们这里只考虑加法运算。
- 比如计算 x - y ,我们可以先计算出 -y 的 radix complement(这里假设是 two's complement), 即 , 最后再减去 保证等式不变。具体公式如下 - 看个具体的例子, 比如 32 - 26。我们通过上面计算已经知道 -26 的 two's complement 表示为 11100110。那下面我们就可以计算了。 到了这里,就与学校教的取反,相加,忽略超出原始位数(这里是八位)的高位数字衔接上了。 但这里面还有一个细节就是,我们一般假设 , 如果 的话,就出问题了。我们来看个示例 16 - 26。 本来我们是要忽略超出位数的高位数字的,但是现在不但没有超出位数,而且结果还不对。


4) 补码中的乘除运算

先吐为快

二的补码?补码这玩意和二有什么关系?计算的时候我可一点没看到“二”呀!就因为是二进制数,所以叫二的补码?我还说这数长得像是我家大黄,所以叫大黄的补码呢!好嘛,看了看 wiki ,又看了看学校讲的 (真是给我气吐了)。two's complement 翻译为二的补码(也有叫二的补数), ones' complement翻译为反码(???)