计算机组成原理 | 定点数加减运算

💻 计算机只会做加法?揭秘定点数加减法的底层魔法

大家好!今天我们要潜入计算机的最深处,聊聊一个看似简单、实则暗藏玄机的话题------定点数的加减法运算

【上一期:定点数移位运算】

你有没有想过,为什么你的电脑和手机能在一瞬间算出成千上万道数学题?其实,在计算机的微观世界里,硬件设计师们为了"偷懒",甚至把减法器都省掉了!因为只要掌握了神奇的编码规则,计算机只需要一个加法器,就能搞定所有的加减运算。

这背后的秘密武器,就是我们今天要聊的主角:原码、补码和无符号数。系好安全带,我们发车啦!🚀


🎭 失败的尝试:直观但"笨拙"的原码

首先出场的是最符合人类直觉的选手------原码 。 它的规则特别简单:最高位作为符号位(0代表正,1代表负),剩下的位表示数值的绝对值。比如4位二进制中,0001是+1,1001是-1。

看起来很完美对吧?但在计算机眼里,原码简直是"灾难"。

我们来做个简单的实验:计算 1 + (-1)

按照原码直接相加:0001 (+1) + 1001 (-1) = 1010

结果 1010 在原码里代表什么呢?代表 -2

这就离谱了,1加-1竟然等于-2?

而且原码里还有 0000(+0)和 1000(-0)两个零,简直是在浪费宝贵的存储空间。

所以,如果用原码做加减法,计算机必须额外设计复杂的电路来判断符号、比较大小,然后再决定是做加法还是减法。这对于追求极致速度的CPU来说,显然是不可接受的。

于是,补码带着光环登场了。


✨ 真正的王者:化减为加的补码

补码的核心思想极其精妙:利用"模运算",把减法变成加法。

举个生活中的例子:现在的钟表指向10点,你想把它拨到5点,有两种方法。

  • 减法思维:逆时针往回拨5个小时(10 - 5 = 5)。

  • 加法思维:顺时针往前拨7个小时(10 + 7 = 17)。因为钟表一圈只有12个小时(模为12),超过的部分自动丢弃,17 - 12 = 5,指针依然指向5点。

在这个例子里,减去5,等价于加上7。这个7,就是-5在模12下的"补数"。

计算机里的二进制也是同理。假设是4位二进制,它的"一圈"(模)是 。

当我们想计算 5 - 3 时,其实就是计算 5 + (-3)

  • 5的补码是 0101

  • -3的原码是 1011,反码是 1100,补码是 1101(取反加一)。

  • 两者相加:0101 + 1101 = 10010

  • 因为只有4位,最高位的1自然溢出被丢弃,剩下 0010,也就是十进制的2。完美!

补码加减法的统一规则:

  • 加法[X+Y]补 = [X]补 + [Y]补(符号位直接参与运算!)。

  • 减法[X-Y]补 = [X]补 + [-Y]补。求 [-Y]补 的方法很简单:把 [Y]补 连同符号位在内,全部按位取反,末位加1。

这样一来,计算机再也不用区分加减法了,统统扔给加法器去处理!


🔢 简单直接的无符号数

除了带符号的定点数,计算机里还有一种无符号数(Unsigned),它没有符号位,所有位数都用来表示数值。

  • 加法:直接按二进制相加。如果最高位产生了进位(比如8位全为1再加1),就会发生"上溢出",此时进位标志(CF)会被置为1。

  • 减法 :同样转化为加法。A - B 等价于 A + (B的补数)。B的补数怎么求?对B的所有位(包括最高位)按位取反,末位加1。如果在变加法后,最高位没有产生进位,说明发生了"下溢出"(结果为负,但无符号数不能表示负数)。

有关溢出检测的方法可以看这里!!!


⚙️ 硬核揭秘:补码加减运算电路

最后,我们把视角拉到芯片层面,看看这些数学原理是怎么变成实实在在的电路的。

其实在硬件里,并没有独立的减法器。无论是无符号数还是有符号数(补码),它们共用同一套加法器电路!这是怎么做到的呢?

想象一个带有"模式开关"(我们叫它 Sub 信号)的加法器:

  1. 当 Sub = 0 时(做加法):电路直通,两个数 X 和 Y 直接进入加法器相加。

  2. 当 Sub = 1 时(做减法)

    • 减数 Y 会先经过一排"非门"(异或门),把所有的0变1,1变0(按位取反)。

    • 同时,Sub 信号还会偷偷给加法器的最低位进位输入端(Cin)送一个 1。

    • 这就完美实现了"取反加一"的操作!

至于大家常听说的溢出(Overflow),那是针对有符号数的。比如两个正数相加,结果却变成了负数(符号位由0变1),这就说明结果超出了机器字长能表示的范围。电路里通常会用异或门来检测这种符号位的异常突变。

补码加减运算电路也是ALU的重要组成部分

有关ALU的可以看这里!!!


📝 课后实战演练

题目一:基础补码减法运算假设机器字长为8位(含1位符号位),请计算

25 - 30 的结果,并用二进制补码写出完整的运算过程。

  • 解析

    1. 首先求两个数的补码:(这里跳了步骤,正常可以先求原码)

      [+25]补 = 0001 1001``[+30]补 = 0001 1110

    2. 将减法转化为加法,需要求 [-30]补。根据"连同符号位取反加一"的规则:[-30]补 = 1110 0010

    3. 执行加法运算:

      0001 1001 (+25)``+ 1110 0010 (-30)

      1111 1011 (结果)

    4. 将结果 1111 1011 转换回十进制验证:符号位为1说明是负数,数值位取反加一得到 0000 0101(即5),所以结果是 -5。运算正确!

题目二:溢出判断挑战 在8位补码系统中(表示范围为 -128 ~ +127),计算 100 + 50,并判断是否发生溢出。

  • 解析

    • 次高位(第6位)相加:1 + 1 产生了进位 1 给符号位。

    • 符号位(第7位)相加:0 + 0 + 1(进位) = 1,没有向更高位产生进位(进位为 0)。

    • 因为"符号位进位"与"次高位进位"不相同 (0 ⊕ 1 = 1),所以发生了正溢出

    1. 求补码:[+100]补 = 0110 0100[+50]补 = 0011 0010

    2. 相加:0110 0100``+ 0011 0010``------------``1001 0110

    3. 溢出判断:我们观察最高位(符号位)的进位和次高位(数值最高位)的进位。

    4. 从结果看,1001 0110 的符号位是1,代表负数。两个正数相加得到了负数,显然结果错误,证实了溢出的发生。

题目三:电路逻辑分析 在一个4位补码加减运算电路中,控制信号 Sub = 1(表示做减法)。此时输入操作数 A = 0101,B = 0011。请问:

  1. 进入全加器的 B'(变换后的B)是多少?

  2. 最低位的进位输入 Cin 是多少?

  3. 最终输出的 4位和 S 是多少?

  • 解析

    1. Sub = 1 时,B 的每一位都要与 1 进行异或运算(按位取反)。B = 0011,所以进入全加器的 B' = 1100

    2. 减法模式下,控制信号会直接连到最低位的进位端,实现"加一"的操作。所以 Cin = 1

    3. 实际执行的运算是

      A + B' + Cin:0101 (A)``+ 1100 (B')``+ 1 (Cin)

      10010

      由于是4位运算器,最高位的1被自然丢弃,最终输出的 S = 0010(即十进制的2,符合 5 - 3 = 2 的预期)。


相关推荐
吃好睡好便好8 小时前
在Matlab中绘制杆状图
开发语言·学习·算法·matlab·信息可视化
Shadow(⊙o⊙)8 小时前
Shell进程替换,自定义Shell解释器——字符串库函数灵活操作!
linux·运维·服务器·开发语言·c++·学习
星幻元宇VR8 小时前
VR禁毒骑行系统|以沉浸式体验提升禁毒宣传教育效果
人工智能·科技·学习·安全·vr·虚拟现实
Hua-Jay9 小时前
OpenCV联合C++/Qt 学习笔记(二十三)----图像校正及单目位姿估计
c++·笔记·qt·opencv·学习·计算机视觉
水木流年追梦9 小时前
大模型入门-预训练、SFT 有监督学习
人工智能·学习·机器学习
魔法阵维护师9 小时前
从零开发游戏需要学习的c#模块,第十八章(2D 碰撞检测与金币收集)
学习·游戏·c#
Cat_Rocky9 小时前
k8s zabbix7学习-设置告警
学习·容器·kubernetes
Upsy-Daisy9 小时前
AI Agent 项目学习笔记(九):网页搜索、网页抓取与资源下载工具
笔记·python·学习
辰海Coding9 小时前
MiniSpring框架学习-增加事件发布的简化 IoC 容器
java·学习·spring·java-ee