Skip to content

浮点数的加减运算

2026 大纲 二(四)2 浮点数的加/减运算(对阶、尾数求和/差、规格化、舍入、溢出判断)。这一条只到"加/减"为止,不含乘除。

五个步骤全是从一个式子里长出来的

浮点加减的五步——对阶、尾数加减、规格化、舍入、溢出判断——不必当成五条流程来记,它们全在这一个式子里:

x±y=(Mx×2ExEy±My)×2Ey

2ExEy 就是对阶,括号里就是尾数加减,把结果还原成标准形式就是规格化舍入,最后查 Ey 有没有出界就是溢出判断

第一步的方向不是随便定的:

🔴 必须小阶向大阶看齐。 小阶的尾数右移,丢的是低位——这是有界的精度损失,还能靠附加位与舍入补救;反过来让大阶的尾数左移,会顶掉规格化尾数的最高有效位这是"错误"与"精度损失"的差别,不是"损失大"与"损失小"的差别。

🔴 对阶绝不引起溢出。 结果的阶码 =max(Ex,Ey)不产生任何新的阶码值——两个操作数本就合法,取其中较大的那个当然也合法。被牺牲的是尾数精度,不是阶码。

⚠️ 对阶右移移出的低位不能立刻丢,要保留下来参加后续的尾数运算、最后统一舍入;IEEE 754 的隐藏位也必须在尾数运算之前还原回去。

交互可视化

加载可视化中...

一、为什么必须先对阶

用十进制看最清楚:0.123×105+0.456×102 不能把 0.1230.456 直接相加——它们的"每一位代表多少"根本不一样,必须先把指数调成相等。

浮点数的尾数是一串没有绝对位置的有效数字,位置信息全在阶码里。 阶码不同,两串尾数的小数点没有对齐,逐位相加得到的是一个毫无意义的数。二进制同理,设 x=Mx×2Exy=My×2Ey,不失一般性设 ExEy,则

x±y=(Mx×2ExEy±My)×2Ey

二、对阶:为什么是小阶向大阶看齐

对阶必然要动一个数的尾数,两种选择:

选择动作后果
小阶向大阶看齐小阶那个数的尾数右移,阶码加到与大阶相等移出的是尾数低位
大阶向小阶看齐大阶那个数的尾数左移,阶码减到与小阶相等移出的是尾数高位

这两种后果不是"损失大小"的差别,而是性质的差别。规格化浮点数的尾数最高有效位一定是 1(IEEE 754 里它甚至是隐藏位),左移必然把这一位顶出寄存器——丢掉的是这个数最重要的那一位,结果与原数毫无关系,本质上等同于尾数溢出。而右移丢掉的是最不重要的低位,损失有界且可补救。

向大阶看齐只丢低位精度;向小阶看齐会丢高位造成溢出

规则:求出阶差,让阶小的那个数的尾数右移,每右移一位阶码加 1,右移位数正好等于阶差。

三、尾数加减

对阶后两数阶码相同,直接对尾数做定点加减。IEEE 754 用定点原码小数表示尾数,实现上通常转成补码运算,与定点补码加减完全相同,符号位参与运算。两个细节:隐藏位要还原对阶时保留的附加位也要参加运算

四、规格化:两种方向补救两种越界

尾数加减的结果通常不再是规格化形式,可能落到两侧:

1.bbb+1.bbb=±1b.bbb(太大)1.bbb1.bbb=±0.0001bb(太小)
触发条件动作次数
右规尾数溢出(绝对值 上界)尾数右移 1 位,阶码加 1最多一次
左规尾数绝对值太小,最高有效位不在该在的位置尾数逐次左移,阶码逐次减 1可能多次

次数为什么一个有界一个无界,也是从式子里读出来的:两个规格化数相加,绝对值最多翻倍,多出的位不会超过一位(加法方向的越界有界);而两个相近的数相减可能几乎全部抵消,前导零的个数没有上界(减法方向的抵消无界)。

🔴 尾数溢出在浮点里不算溢出。 双符号位出现 01.xx / 10.xx 时,右规一次就救回来了,数值完全正确、只损失最低一位精度。浮点数用阶码换来了这种自我修复能力,这是它与定点数最本质的差别之一。

补码双符号位下的规格化判据:正数 00.1xx、负数 11.0xx,即符号位与最高数值位不同。出现 00.0xx / 11.1xx 要左规,出现 01.xx / 10.xx 是尾数溢出、要右规。

五、舍入:右移必然丢位,丢的位必须被处理

对阶右移和右规右移都会把尾数低位挤出去。这些位不能一丢了之——丢弃就是"总是向零方向取整",误差单向累积,一段运算下来结果会系统性偏小。

IEEE 754 规定中间结果右边至少额外保留两位附加位

名称定义
G(guard)保护位 / 警戒位紧跟尾数右边那一位,保护尾数右移出去的位
R(round)舍入位保护位右边那一位,用于判断舍入方向
S(sticky)粘位只要舍入位右边有任何非 0 数字,S 就置 1,否则置 0

举个十进制的类比:保留两位小数时 1.2400+0.0050=1.2450 正好卡在 1.241.25 中间;若多保留一位粘位信息(真实值其实是 0.00503),结果 1.24503 就明显更靠近 1.25,舍入方向不再含糊。

IEEE 754 的四种舍入模式

模式规则
就近舍入到偶数(默认)非中间值时即"0 舍 1 入";正好在中间时,强迫结果的末位为偶数
+ 舍入总取数轴右边最近的可表示数
舍入总取数轴左边最近的可表示数
0 舍入(截断)直接截去多余位,取更靠近原点的那个可表示数;最简单,误差最大

"中间值舍到偶数"不是随便定的:如果一律"逢中进位",大量中间值会被统一推向同一方向,误差同样单向累积。舍到偶数让中间值一半向上、一半向下,长期统计上误差互相抵消。判断"是不是正中间"的机械判据见 浮点数表示(IEEE 754)

六、溢出判断:为什么它值得单独成一步

浮点数的溢出不看尾数,只看阶码

判据只有一条:这一步把阶码往哪个方向动了。

步骤阶码怎么动可能上溢可能下溢
对阶小阶升到大阶,结果阶码 =max(Ex,Ey)
尾数加减不动阶码
左规每次减 1(可能多次)
右规加 1(最多一次)
舍入进位顶溢尾数 再右规,阶码加 1

🔴 溢出只看阶码。 唯一的判据是阶码有没有被推出表示范围:上溢时报异常或把结果置 ±,下溢时一般置 ±0

🔴 舍入也能引起上溢,别只盯着右规。 舍入本身只碰尾数,但它的进位可能把尾数顶溢出(1.11110.000),从而间接逼出一次右规、阶码加 1。所以"右规和尾数舍入都可能引起阶码上溢"这句话是正确的。

🔴 舍入是整个流程里唯一的回路。 严格顺序是:对阶 → 尾数运算 → 规格化 → 舍入 →(若舍入进位顶溢尾数)再右规 → 溢出判断。

硬件实现上,右规前会先判断阶码是否已达上界:若是,直接判定为指数上溢,不再右规;左规同理,先判断阶码是否已达下界。

两道加法逐拍走查:五个步骤在纸面上分别长什么样,以及"大数吃小数"是怎么发生的(想核对自己每一步的中间结果时展开)

格式:阶码 4 位(补码)、尾数双符号位 + 5 位数值(补码)。

(一)A+B[EA]=0101(+5)[MA]=00.11011[EB]=0011(+3)[MB]=00.10100

① 对阶 阶差 ΔE=53=2B 的阶小,MB 右移 2 位:

00.1010000.00101(移出 00, 无损失)

阶码统一为 0101

② 尾数相加

00.11011+00.00101=01.00000

双符号位为 01尾数溢出——注意这在浮点里不算结果溢出。

③ 规格化 右规:尾数右移 1 位,阶码加 1。

01.0000000.10000,E=0101+1=0110 (+6)

④ 舍入 右规移出的是 0,无需进位;对阶时也未丢位。

⑤ 溢出判断 阶码 +6 在 4 位补码范围 [8,+7] 内,不溢出。

结果0.10000×26=32。核对:A=0.110112×25=27B=0.101002×23=527+5=32

(二)大数吃小数:同一格式下 A 的阶码 0111(+7)、尾数 00.10000B 的阶码 0001(+1)、尾数 00.10000。阶差 ΔE=6,而尾数只有 5 位数值位,MB 右移 6 位后全部有效位都被移出

00.10000 右移 6 位 00.00000

于是 A+B=A=0.10000×27=64。真值是 64+1=65,机器给出 64。

这不是实现缺陷,是有限位数的必然:在阶码为 +7 的这一档上,相邻两个可表示数之间的间隔本来就大于 1,65 根本没有对应的编码。就算保留了附加位,就近舍入后的结果仍然是 64。

由此推出加法不满足结合律(x+y)+zx+(y+z) 可以得到不同结果——一个"大数"和一个"小数"相加时小数被吃掉,而如果先让两个小数相加,它们的和可能就大到不会被吃掉了。

浮点乘除法(超纲选读,但它能把"阶码是移码"讲透)

大纲「二(四)浮点数的表示和运算」只有表示与加/减两条,不含乘除。复习时间紧就跳过。

浮点乘除不需要对阶——阶码直接加减、尾数直接乘除:

A×B:E=EA+EBbias,M=MA×MBA÷B:E=EAEB+bias,M=MA÷MB

为什么要减/加一个 bias:IEEE 754 的阶码用移码表示,机器里存的是"真值 + 偏置量"。两个移码相加,偏置量被算了两次,必须减掉一个;两个移码相减,偏置量互相抵消,必须再加回一个。

若题目的阶码用补码表示(上面走查用的就是),则直接 E=EA+EBE=EAEB,不涉及 bias。先看清用哪套阶码体系,再套公式。 乘除之后同样需要规格化与舍入。

考点速记

  1. 尾数只有有效数字、位置全在阶码里,所以对阶是绕不过去的第一步;必须小阶向大阶看齐,右移丢低位是有界的精度损失,左移顶掉最高有效位是数值错误。对阶后结果阶码 =max(Ex,Ey)不产生新阶码值,因此绝不溢出
  2. 规格化右规最多一次、左规可能多次(加法越界有界、减法抵消无界);尾数溢出不算溢出,右规就能救回来——浮点数用阶码换来了这种自我修复能力。
  3. 溢出只看阶码左规可能下溢,右规与舍入可能上溢,对阶与尾数加减都不可能;舍入进位顶溢尾数会触发再一次右规,这是流程里唯一的回路。阶差超过尾数位数时发生大数吃小数,直接导致加法不满足结合律。

这一节在真题里被考过的形式(下方「真题练习」逐题对应):

  • 给 I/II/III/IV 四条关于浮点加减的叙述,问哪几条正确:这是本篇最典型的一道,四条几乎必然覆盖上面三条速记——"对阶不会引起上溢或下溢"()、"右规和尾数舍入都可能引起阶码上溢"(,舍入进位会间接逼出右规)、"左规时可能引起阶码下溢"()、"尾数溢出时结果不一定溢出"(,右规能救回来)。判每一条时都回到"这一步把阶码往哪个方向动了"。
  • 给两个浮点数,问和/差的机器数:五步走完整流程,⚠️ 对阶右移移出的位先留着参加运算、最后统一舍入,别提前丢。
  • 问某个表达式在浮点下与数学上是否相等:考的是大数吃小数——阶差大到超过尾数位数时,小数右移后有效位全被移出、加了等于没加,所以浮点加法不满足结合律,数值程序不能随意重排加法顺序。

易错:把对阶方向弄反。必须小阶向大阶看齐。

易错:认为对阶会引起溢出。它不产生新的阶码值。

易错:把尾数溢出当成浮点溢出。右规一次就好,数值仍然正确。

易错:只把"右规"算作可能上溢的步骤,漏掉舍入。

教材出处
  • 十进制引例、x±y=(Mx×2ExEy±My)×2Ey、"计算机中实现上述计算过程需要经过对阶、尾数加减、规格化和舍入 4 个步骤,此外还必须考虑溢出判断和溢出处理"、对阶"小阶向大阶看齐"、"尾数右移时低位移出的位不要丢掉,应保留并参加尾数部分的运算":袁春风《计算机组成与系统结构》第 3 版 §3.5.1 浮点数加减运算,印刷页 p80
  • 尾数加减需还原隐藏位、右规/左规的触发形式与动作、溢出判断只在涉及阶码求和/差的两处(右规与舍入、左规)进行、"浮点数的溢出并不以尾数溢出来判断,尾数溢出可以通过右规操作得到纠正":同书印刷页 p81
  • 浮点加减运算部件的五步执行流程、"由于浮点加减运算中需要对阶并最终进行舍入,因而可能导致'大数吃小数'的问题,使得浮点数运算不能满足加法结合律":同书印刷页 p82
  • 保护位(guard)、舍入位(round)、粘位(sticky)的定义与"IEEE 754 标准规定浮点数运算的中间结果右边必须至少额外保留两位附加位"、加法结合律的反例:同书 §3.5.2 浮点运算的精度和舍入,印刷页 p83
  • IEEE 754 四种舍入模式及十进制对照示例、就近舍入到偶数为默认模式、粘位如何减少"正好在中间"的情形:同书印刷页 p83–p84
  • 对阶原则"首先要求出阶差,再按小阶向大阶看齐的原则,使阶小的尾数向右移位,每右移一位阶码加 1":唐朔飞《计算机组成原理》第 3 版 §6.3 浮点四则运算,印刷页 p270
  • 补码双符号位下的规格化判据、左规与右规的定义与动作:同书印刷页 p271
  • "0 舍 1 入"法与"恒置 1"法、"这样做可能使尾数又溢出,此时需再做一次右规":同书印刷页 p272

相关知识

浮点数表示(IEEE 754)定点补码加减运算

真题练习

相关真题(3题)