专栏文章
简要介绍补码的原理
科技·工程参与者 58已保存评论 63
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 63 条
- 当前快照
- 1 份
- 快照标识符
- @mhz5rzz0
- 此快照首次捕获于
- 2025/11/15 01:55 4 个月前
- 此快照最后确认于
- 2025/11/29 05:25 3 个月前
补码对于我来说向来是一个神秘的概念。主要因为不论是课堂所授,教材所述,博文所记,但凡涉及补码相关,无不罗列“取反加一”之类的生涩定义,至多列举几个实例,而再无详解。我却在近日阅读《深入理解计算机系统》一书时发现关于补码原理的讲解。此书所述亦无长篇大论,却简洁精要,直入本质,令人恍然大悟,拍手称快。故作此文以记之,一来留作备忘,二来造福后人,减少迷惑无力之困境。
首先考虑一个位二进制数,可以用一个向量来表示它的位原码表达形式。
所谓的向量,不过是个或的序列,不必见到不熟悉的数学知识就大惊失色,几欲先走。
在原码中,第位表示,而补码实质上是用最高位,即符号位表示,其余位仍表示。
用最高位表示是否是最初设计补码时的考虑尚不得知,网络上也有一篇从模意义角度出发的讲解。但不可否认,是一个极简单又十分正确的理解。
例如对于位补码二进制数,它的十进制表示为。
这里借用《深入理解计算机系统》中的图片来更直观地说明符号位的作用:

如此一来便可以发现,位有符号整数(即补码表示的二进制数)实质上相当于把位无符号整数(即原码表示的二进制数)的后一半映射到负数,而前一半的意义保持不变。二进制的美好性质在这里得到了充分的体现。

根据最高位表示的解释,便可以推导一对相反数的补码表示的关系:
令正数,由于A是正数,所以符号位,。
是负数,所以其最高位应为,不妨将中的最高位变为1,其余位不变,观察其变化。
令,2的整数幂减去低位的二进制数有什么特点?
需要注意到,所以。
其中就是把除了最高位全部取反的结果。
那么不妨令,则,即。
是除最高位取反的结果,而是最高位取反的结果,那么就是全部取反的结果,所谓取反再加一的计算方法可以由此推来。
回顾刚才的推导过程,不和谐的实质上是把无符号整数的后一半通过减法映射到负数时自然出现的。进一步地说,会出现本质上是因为一个位全是的二进制数和第位是,剩下位为的二进制数之间相差为。
了解了补码的原理,关于整数表示的一些知识也变得容易起来。
例如逻辑右移和算数右移。所谓逻辑右移,就是右移位后前位补零,例如位二进制数逻辑右移位的结果为。而算数右移会在前位补符号位,例如算数右移位结果为,而算数右移位结果为。
如果对补码采用算术右移,则不仅能做到符号位不变(补上了相同的符号位),还能做到绝对值的变化与正数右移时的变化一致。一方面可以理解为补码转进制表达时如果是负数,则需要取反,这时补上的就会转成,另一方面可以类比上文,以的次幂的形式进行数学推导:
,这就等价于最高位为位的二进制负数。
文末为感兴趣的读者提供三道思考题:
(在C语言中)
-
为什么abs(-2147483648)=-2147483648?
-
什么情况下i<=strlen(b)-1会出现错误?应该怎么更改以避免这个错误?(提示:strlen()函数的返回值为无符号整数)
-
为什么在C语言的limits.h头文件中要把int类型变量的最小值INT_MIN定义为(-INT_MAX-1),而不是直接定义为-2147483648?
这三道思考题引导读者探索更多关于整数表示的知识。
最后再次推荐《深入理解计算机系统》一书,它介绍了有关计算机系统的诸多原理,最重要的是紧密贴合实际,既容易理解又引人入胜,推荐给每一个对计算机系统感兴趣的人。
相关推荐
评论
共 63 条评论,欢迎与作者交流。
正在加载评论...