第 2 章 名词库

这一页是复习主入口。 目标是把第 2 章的名词收全,并把每个词的边界和适用范围钉死。

每条最多四行:是(定义)/不是(划掉最常见的误解)/易混(成对的对手)/范围(该结论在什么条件下才成立)。

建设进度:✅ 2.1 数制与编码 ✅ 2.2 运算方法和运算电路 ✅ 2.3 浮点数的表示与运算 (全章完整)


2.1.1 进位计数制及其相互转换

基数 (Radix / Base)

  • 是:某进位计数制中可用数码的个数。 进制的数码是 。
  • 不是:不是”位数”,也不是”位权”。
  • 易混:↔ 位权(基数是常量 ,位权是 ,随位置变化)。

位权 (Weight)

  • 是:某一位所代表的倍数,等于 , 是该位相对小数点的位置(左侧从 0 递增,右侧递负)。
  • 不是:不是该位上的数码本身。
  • 易混:位权展开 是一切进制转换的唯一原理,两个方向只是”代入求和”与”反解 “的区别。

除基取余 / 乘基取整

  • 是:十进制转 进制的两个操作。整数部分除基取余、逆序读;小数部分乘基取整、顺序读。
  • 不是:两者的方向恰好相反,不能混用。
  • 范围:整数部分的转换必然终止;小数部分的转换不保证终止。

有限二进制小数的判据

  • 是:十进制小数 能被二进制有限位精确表示,当且仅当 可写成 (最简分母只含质因子 2)。
  • 不是:不是”位数不够”的问题, 在任何位宽的二进制下都无法精确表示。
  • 易混:这是浮点数不精确的唯一根源,与 IEEE 754 的尾数长度无关。
  • 范围:一般形式为” 的最简分母的质因子全是 的质因子”;有限位二进制小数转十进制一定也有限,反之不然。

容量的 K/M/G vs 速率的 K/M/G

  • 是:容量按 (1MB B);频率、带宽、传输率按 (1MHz Hz)。
  • 不是:不是可以互换的同一个前缀。
  • 范围:判据是”这个量是否由二进制位数决定”——容量、块数、页数按 ;由时间决定的量按 。第 3 章算存储带宽、第 6 章算总线传输率时会直接影响答案。

BCD 码 (Binary-Coded Decimal)

  • 是:每个十进制位单独用 4 位二进制编码。 的 8421 BCD 是 0001 0101。
  • 不是:不是把整个十进制数转成二进制(那是 1111)。
  • 范围:王道 2026 版第 2 章目录中已无 BCD 码的三级节(见 权威目录)。仅在旧题里可能遇到,不作为复习重点。

2.1.2 定点数的编码表示

定点数 (Fixed-Point Number)

  • 是:小数点位置由约定固定的数。408 只用两种约定:定点整数(小数点在最低位之后)、定点小数(小数点在符号位之后)。
  • 不是:机器不为小数点分配任何一位,小数点在位串里不存在。
  • 易混:↔ 浮点数(把小数点位置也编进位串)。
  • 范围:同一串位在两种定点约定下相差 倍,但编码规则、加减规则、溢出判据完全通用——做题时最后再确定小数点位置即可。

真值 / 机器数

  • 是:真值是带正负号的实际数值();机器数是它在机器里的位串(1111 0011)。
  • 不是:机器数永远是一串无符号的 0/1,它的数值必须靠编码规则解释。
  • 易混:同一机器数在原/反/补/移四种编码下是四个不同的真值。

原码 (Sign-Magnitude)

  • 是:最高位为符号(0 正 1 负),其余位为绝对值。
  • 不是:符号位不能参与运算——原码加减必须先比较绝对值大小。
  • 易混:有 两个零;表示范围对称,为 。
  • 范围:原码在实际机器中只用于浮点数尾数(部分教学机型)和乘法运算的中间过程,整数运算已全面被补码取代。

反码 (Ones’ Complement)

  • 是:正数同原码;负数为符号位置 1、数值位逐位取反。
  • 不是:不是”补码减一”的定义,而是补码的中间步骤。
  • 易混:有 两个零;加法需要”循环进位”(最高位进位加回最低位)。
  • 范围:实际机器不使用反码。408 里它只作为求补码的中间步骤和辨析对象出现。

补码 (Two’s Complement)

  • 是:正数同原码;负数为 ,等价于”反码加 1”。现代机器有符号整数的唯一编码。
  • 不是:不是一种”记法”,而是把负数替换成模 下与它同余的正数,好让减法器消失。
  • 易混:零唯一;范围 ,负数侧多一个。
  • 范围:C 标准直到 C23 才强制要求补码;此前允许原码和反码。题目问”C 标准是否保证”时要注意。

补码的模运算解释

  • 是: 位加法器是模 的运算器,。“减 “与”加 “给出完全相同的位串。
  • 不是:丢弃最高位进位不是”忽略错误”,取模就是这个动作本身。
  • 易混:这条解释回答”为什么减法能变成加法”。

补码的权值解释

  • 是:,即最高位的权是 ,其余位权照常为正。
  • 不是:最高位不是”符号标记”,它是一个权为负的普通数值位。
  • 易混:这条解释回答”为什么符号位可以参与运算”、“为什么补码多表示一个 ”、“为什么符号扩展是复制符号位”。

快速求补码的四种方法

  • 是:① 定义法(数值位取反加 1);② 扫描法(从右往左,第一个 1 及其右边照抄,左边取反);③ 减法法();④ 相反数法(补 连符号位一起取反加 1 得 补)。
  • 不是:四者给出的位串完全相同,区别只在手算速度。
  • 易混:方法①的取反不含符号位,方法④的取反包含符号位——这是最容易混的一处。
  • 范围:方法④对正负数都适用,减法电路用的就是它;但 补 是例外,取反加一后仍是自身。

移码 (Biased / Excess Code)

  • 是:移,等于把补码的符号位取反。
  • 不是:不是补码的另一个名字。
  • 易混:移码的位串按无符号数比较,顺序与真值顺序一致——这是它存在的唯一理由。
  • 范围:只用于浮点数的阶码。且 IEEE 754 的偏置是 (127/1023),不是教材移码的常规偏置 。

表示范围的非对称性

  • 是: 位补码范围 ,负数侧多一个,因为 1000…0 这个""被回收成 。
  • 不是:不是精度问题,是编码分配问题。
  • 易混: 有补码,但没有对应的原码和反码。
  • 范围:由此导出 、 无法表示、 溢出。定点小数下的对应形式是”补码能表示 “。

2.1.3 整数的表示

无符号整数 (Unsigned Integer)

  • 是:无符号位, 位全部参与位权展开,范围 。硬件上是一个模 的环。
  • 不是:不是”非负整数”的精确对应——它没有负数,减出负值会绕回大正数。
  • 易混:for (unsigned i = n; i >= 0; i--) 是死循环,因为 i >= 0 恒真。
  • 范围:sizeof 返回 size_t(无符号),所以 a - b < 0 在两者均为 size_t 时永远不成立。

同一位串的两种解释

  • 是:(当 )或 (当 )。同一串位,两种读法差 。
  • 不是:加法器不区分有符号与无符号,两者用同一个部件、产生同一串位。
  • 易混:区别只发生在五处:溢出判据(CF/OF)、大小比较、右移(逻辑/算术)、除法指令、位数扩展(零/符号)。
  • 范围:这五处正是所有”有符号 / 无符号”考题的出处;“有没有符号”是解释的属性,不是数据的属性。

回绕 (Wrap-around)

  • 是:结果对 取模后落回表示范围。,。
  • 不是:不是错误,是无符号运算定义良好的行为。
  • 易混:↔ 溢出(“超范围”这一事实)↔ 未定义行为(C 语言层面对有符号溢出不作承诺)。三者是三个层面的概念。
  • 范围:硬件永远在做模 运算,从不”出错”——它只置位 CF/OF 然后继续。是否算作错误由使用者按类型决定。

特征位串

  • 是:0xFFFFFFFF 有符号是 、无符号是 ;0x80000000 有符号是 、无符号是 ;0x7FFFFFFF 是 INT_MAX。
  • 易混:“全 1 就是 “与字长无关,8/32/64 位全 1 都是 (由权值解释:)。

2.1.4 C 语言中的整数类型及类型转换

整数提升 (Integer Promotion)

  • 是:表达式求值前,所有窄于 int 的整型(char、short、位域、枚举)先被提升为 int(int 装不下则为 unsigned int)。
  • 不是:提升永远不改变值,意外发生在提升之后的下一步。
  • 易混:char + char 的结果类型是 int,不是 char。
  • 范围:移位运算的两个操作数各自独立做整数提升,但不做通常算术转换——c << 1 结果是 int,不截断。

通常算术转换 (Usual Arithmetic Conversions)

  • 是:先各自整数提升;符号性相同则转较宽者;符号性不同时,无符号方更宽或等宽 → 全转无符号,有符号方更宽且能容纳全部值 → 全转有符号。
  • 不是:不是”看到 unsigned 就转无符号”。
  • 易混:int vs unsigned int → i < u 中 变成 4294967295,为假;但 int vs unsigned short → short 先被提升为 int,为真。
  • 范围:判据是”提升之后两边是否仍符号性不同”,不是字面上有没有 unsigned。

零扩展 / 符号扩展

  • 是:窄转宽时补高位。源是无符号 → 补 0;源是有符号 → 补符号位。
  • 不是:与目标类型的符号性无关,只看源类型。
  • 易混:int x=-1; unsigned long u=x; 得 0xFFFF...F(先按有符号扩到 64 位,再重解释),不是 0x00000000FFFFFFFF——先扩展、后重解释。
  • 范围:符号扩展保值的证明是 ,因此复制一位是唯一保值的补法,复制多少次都成立。

截断 (Truncation)

  • 是:宽转窄时丢弃高位,保留低 位,再按目标类型解释。等价于对 取模。
  • 不是:不会报错,也不置任何标志位,是显式转换的正常语义。
  • 易混:(short)65535 == -1(低 16 位 0xFFFF 按有符号 short 读)。

值转换 vs 位型重解释

  • 是:(int)f 是值转换,生成真正的转换指令;*(int*)&f 是位型重解释,一条指令都不生成。
  • 不是:“强制类型转换 = 位型重解释”只在同宽度整数之间偶然成立,不是通则。
  • 易混:(int)3.9f == 3;*(int*)&3.9f == 1081291674。两者毫无关系。

2.2.1 基本运算部件

半加器 / 全加器

  • 是:半加器只加两个位(,);全加器接受第三个输入 (低位进位)。
  • 不是:判据是”接不接受低位进位”,不是”能不能算两个数”。
  • 范围: 位加法器理论上只需 1 个半加器 + 个全加器;但为支持减法()和多字长运算,实际机器最低位也用全加器。

进位生成 / 进位传递

  • 是:(这一位自己产生进位)、(把低位进位原样传出)。统一写成 。
  • 不是: 不是”这一位有进位”,而是”这一位会不会挡住进位”。
  • 易混:这一个式子是先行进位加法器的全部基础。

串行进位加法器 / 行波进位

  • 是: 个全加器首尾相接,进位逐位传递。
  • 不是:慢的不是求和(求和天然并行),慢的是进位链。
  • 范围:进位延迟与位数成正比(约 级门),32 位要等约 64 级门延迟,直接决定了 CPU 时钟周期的下限。

先行进位加法器 (CLA)

  • 是:把 逐层展开,使每个 只依赖 、 和 ,组内各位进位同时产生。
  • 不是:不是”取消了进位链”,而是把进位链换成了扇入更大的组合逻辑——用面积换时间。
  • 易混:单级先行进位是”组内并行、组间串行”;多级先行进位再加一层 CLA,需要成组的 、。
  • 范围: 的表达式已有 5 项、最长一项 5 个输入,扇入限制使实际按 4 位一组。

加减统一电路

  • 是:每位 先过一个异或门 ,同时 。 时算 。
  • 不是:不需要减法器。
  • 易混:""由本来就存在的 免费提供,减法的额外成本只有 个异或门。

ALU (Arithmetic Logic Unit)

  • 是:封装了加减法器和逻辑运算阵列的组合逻辑部件,由 选择功能,输出结果与标志位。
  • 不是:ALU 不保存状态——数据靠寄存器保存,标志位靠标志寄存器锁存。因此 ALU 不能单独完成累加。
  • 易混:乘法器 / 除法器通常在 ALU 之外;移位器可在 ALU 内也可在 ALU 外。
  • 范围: 由控制器根据指令操作码产生,是第 5 章控制器设计的输出之一。

2.2.2 定点数的移位运算

逻辑移位 (Logical Shift)

  • 是:不承认符号位,左右移空出的位一律补 0。
  • 不是:用在有符号数上会出错——1111 1111()逻辑右移变成 0111 1111()。
  • 易混:↔ 算术移位。判据是”补 0 还是补符号位”,不是”数据本身是正是负”。

算术移位 (Arithmetic Shift)

  • 是:保持真值符号与倍数关系的移位。补码右移补符号位;原码正负数移位都补 0;反码负数一律补 1。
  • 不是:符号位不参与移动(补码右移复制符号位是”不动”的另一种说法)。
  • 易混:算术左移与逻辑左移的位串完全相同(都补 0),区别只在判溢出的方式:算术左移看”移出位 新符号位”,逻辑左移看 CF。
  • 范围:算术右移向负无穷取整,C 的整数除法向零截断——被除数为负且不整除时相差 1(,)。所以 x/2 → x>>1 的优化只对无符号数和非负数成立。

循环移位 (Rotate)

  • 是:移出的位绕回另一端。小循环(不带进位位)直接绕回;大循环(带进位位)把 CF 当作第 位一起循环。
  • 不是:不对应乘除 2,也不产生溢出。
  • 易混:循环移位不改变位串中 1 的个数,逻辑移位和算术移位会。
  • 范围:大循环的周期是 而不是 ;它的实际用途是多字长数据的移位,没有 CF 参与则两个寄存器之间的那一位会丢失。

移位器 / 桶形移位器 (Barrel Shifter)

  • 是:执行移位的硬件。普通移位寄存器一次移一位,移 位要 个周期;桶形移位器用多级 MUX, 级即可移任意位数。
  • 不是:三类移位都不需要 ALU 参与——移位部件本身即可完成。
  • 易混:移位部件既可集成在 ALU 内(由 选择),也可独立(由 控制)。两种实现都真实存在。
  • 范围:数据通路题的判据是”图上有没有单独的移位部件”——有就由它做,没有就由 ALU 做。两种画法答案不同,但都不算错。

C 的移位语义

  • 是:x << k 低位补 0;x >> k 对无符号数是逻辑右移(标准强制),对有符号数是实现定义(实际几乎都是算术右移)。
  • 不是:x << 32(x 为 int)不是”清零”,是未定义行为。
  • 范围:三个未定义行为——移位量 类型宽度、移位量为负、有符号左移溢出。

2.2.3 定点数的加减运算

补码加减规则

  • 是:补补补。符号位一起参与运算,最高位进位丢弃。
  • 不是:丢弃进位不是忽略错误,是取模本身。
  • 易混:原码加减要先判符号、再比较绝对值、再决定谁减谁,控制逻辑复杂一个量级,因而被淘汰。

溢出 (Overflow)

  • 是:真值结果超出该编码在该字长下的表示范围。
  • 不是:不是”最高位有进位”(那是 CF)。进位是”位串装不下”,溢出是”符号被改变”。
  • 易混:三种判据等价——① 同号相加、结果异号;② ;③ 双符号位不同。
  • 范围:异号相加绝不溢出;减法转成加相反数后,只有异号相减才可能溢出。 这两条能省掉一半判断。

双符号位 / 变形补码 / 模 4 补码

  • 是:运算过程中把符号位复制成两位。结果 00 正常正数、11 正常负数、01 上溢、10 下溢。
  • 不是:存储时仍只用一位符号位,双符号位只是运算过程/手算的技巧。
  • 易混:高位符号位是结果的真正符号,低位是”单符号位下会看到的表面符号”。01 = 真符号为正、表面为负 → 上溢。
  • 范围:两位符号位是否相同,等价于 ,本来就是同一个异或。

CF / OF / ZF / SF

  • 是:(无符号进位/借位)、(有符号溢出)、(结果全 0)、(结果最高位)。
  • 不是:四个标志同时产生,不是四选一;机器不知道该看哪个。
  • 易混:0xFF+0x01 → CF=1、OF=0;0x7F+0x01 → CF=0、OF=1。同一串位,两种视角的对错判断相反。
  • 范围:减法时 CF 是借位标志,因为 时 表示”够减”。无符号比较大小 = 做减法看 CF。 选择看哪个标志的是编译器(按变量类型选条件跳转指令)。

2.2.4 定点数的乘除运算

乘积位宽

  • 是: 位 位的积最多 位,且这是紧的()。
  • 不是:得到 位是正常结果,不是溢出。
  • 易混:C 中 int * int 的结果类型仍是 int,高 32 位被丢弃;要得到完整积须先转宽类型 (long long)a * b。
  • 范围:x86 的 imul 单操作数形式其实同时产生了 EDX:EAX 两半,是 C 的类型规则丢掉了高半部。

部分积 (Partial Product)

  • 是:乘法迭代过程中累积的中间结果。机器做法是部分积右移而非被乘数左移,这样加法器只需 位宽。
  • 易混:乘数寄存器与乘积低半部共用一组触发器——部分积右移腾出的位置正好装移出的低位。

原码一位乘法

  • 是:符号单独异或,数值部分用绝对值做 轮”看乘数最低位 → 加 或加 0 → 右移”。
  • 不是:符号不参与数值运算。
  • 易混:部分积用逻辑右移(补 0),因为全程为正。
  • 范围:缺点是符号要单独处理、最后要拼接,控制逻辑不统一。

补码一位乘法 / Booth 算法

  • 是:附加位 ,每轮看相邻两位 :01 加 补、10 加 补、00 与 11 不动,然后算术右移。共 轮( 含符号位)。
  • 不是:不需要单独处理符号,符号自动正确。
  • 易混:部分积用算术右移(补符号位),与原码乘法的逻辑右移相反。判据是”部分积有没有符号”。
  • 范围:原理是恒等式 ——一段连续的 1 换成一次加、一次减。这与编译器把 优化成 是同一个恒等式。

阵列乘法器

  • 是:把 个”与门 + 全加器”排成方阵,同时算出所有部分积再并行归约,延迟降到 或 。
  • 范围:代价是门数从 涨到 。这是本章第三次”面积换时间”(前两次是先行进位加法器、桶形移位器)。

恢复余数法

  • 是:每轮”余数左移、减除数”;结果为负则加回除数恢复,商上 0;否则商上 1。
  • 不是:“加回去”不产生任何信息,纯粹是撤销。
  • 范围:最坏情况 轮做 次加减。

加减交替法 / 不恢复余数法

  • 是:余数 → 商上 1,下轮左移后减除数;余数 → 商上 0,下轮左移后加除数。
  • 不是:不需要恢复余数——因为 可由 一步算出。
  • 易混:每轮固定一次加减,共 次,比恢复余数法最多省 次。
  • 范围:收尾必须校正——最后一轮结束后若余数为负,要再加一次除数。这一步最容易漏。

除法溢出

  • 是:商装不下。定点小数要求 ;定点整数要求商在 位内。除数为 0 也是。
  • 不是:这是唯一会让机器真的停下来的定点运算——x86 上触发 #DE 除法错误异常,而加减乘溢出只置 OF 后继续。
  • 易混: 溢出( 超出 int),是补码非对称性的又一后果。
  • 范围:“除以零在 C 里是未定义行为”是语言层说法,“触发 #DE 异常”是这台机器实际发生的事,两者不同层面。浮点除以零则得 ,不异常。

C 的整数除法取整方向

  • 是:C99 起规定整数除法向零截断,取模符号跟随被除数。,,恒等式 (a/b)*b + a%b == a 始终成立。
  • 易混:与算术右移的向负无穷取整不同,负数不整除时差 1。

2.3.1 浮点数的表示

浮点数 (Floating-Point Number)

  • 是:,把小数点位置也编进数里。
  • 不是:不是”能表示更多的数”—— 位仍只有 个可表示值。它做的是把有限的表示能力按相对精度重新分配:靠近 0 密、远离 0 疏。
  • 易混:“浮点数在数轴上不等距”是理解一切浮点问题的钥匙。
  • 范围: 附近,float 相邻两个可表示数相差 。

阶码 (Exponent) / 尾数 (Mantissa / Significand)

  • 是:阶码决定范围,尾数决定精度。
  • 不是:两者都不是唯一因素——最大值是 而非 (尾数有微小贡献);精度是相对精度。
  • 易混:总位数固定时,阶码每多一位范围按平方级扩大,尾数每多一位精度翻倍。float→double 阶码只加 3 位、尾数加 29 位,因为范围已够、精度是瓶颈。

规格化 (Normalization)

  • 是:约束尾数最高有效位必须有意义。IEEE 754 采用 形式。
  • 不是:规格化 精确。 规格化后尾数无限循环,存进 23 位必被舍入。
  • 易混:目的是编码唯一(否则 无法比较判等)。
  • 范围:浮点不精确的根源在进制转换,不在位数分配——增加尾数位只能减小误差,永远不能消除。

隐藏位 (Hidden Bit / Implicit Leading Bit)

  • 是:规格化后小数点前那位必然是 1,因而不存储,白得一位精度。
  • 不是:非规格化数没有隐藏位 1,阶码全 0 时改用 。
  • 易混:float 尾数字段 23 位、有效位 24 位;double 字段 52 位、有效位 53 位。

IEEE 754 的偏置

  • 是:偏置为 (单精度 127、双精度 1023),而不是教材移码的常规偏置 。
  • 不是:阶码字段的全 0 与全 1 被保留,可用值只有 ,对应实际指数 。
  • 易混:题目问”阶码用什么码”答移码;问”偏置是多少”答 127。两问常连着出。
  • 范围:偏置取 127 使最小规格化数的倒数不上溢:;若偏置为 128,,上溢。

五类编码

  • 是:阶码 → 规格化数 ;阶码全 0 且 → ;阶码全 0 且 → 非规格化数;阶码全 1 且 → ;阶码全 1 且 → NaN。
  • 不是:不能对全 0 / 全 1 阶码继续套规格化公式。
  • 易混:先判类别,再套公式——这一步绝不能跳过。

非规格化数 (Denormal / Subnormal)

  • 是:阶码全 0、尾数非 0。值为 。
  • 不是:实际指数是 而不是 ,且隐藏位是 0 不是 1。两处都反直觉。
  • 易混: 的规定是为了与最小规格化数平滑衔接(最大非规格化数 紧挨着 ,中间无断层)。
  • 范围:它实现逐级下溢——没有它,比 小的数直接变 0,会出现 a != b 却 a-b == 0。代价是精度递减。

NaN / 无穷

  • 是:NaN 由 、、 产生; 由上溢或非零数除以 0 产生。
  • 不是:——NaN 与任何值(含自身)的比较都为假,!= 除外。
  • 易混:判断 NaN 的标准写法是 x != x。 为真(尽管有两个零编码)。
  • 范围:由此 if (a<b) …else… 与 if (a>=b) …else… 在有 NaN 时走的分支不同,两者不是取反关系。

关键边界值(单精度)

  • 是:最小正非规格化数 (0x00000001);最小正规格化数 (0x00800000);最大规格化数 (0x7F7FFFFF); 是 0x3F800000。
  • 易混:双精度对应 、、。
  • 范围:有效数字位数:单精度 → 约 7 位;双精度 53 位 → 约 15~16 位。

2.3.2 浮点数的加减运算

五步流程

  • 是:对阶 → 尾数求和 → 规格化 → 舍入 → 判溢出。
  • 不是:顺序不能调换。判溢出必须放最后,因为规格化会改变阶码。

对阶 (Exponent Alignment)

  • 是:求阶差,把阶码小的数的尾数右移,同时其阶码增大,直到两阶相等。
  • 不是:绝不能大阶向小阶看齐——那要左移尾数,丢的是最高有效位,结果彻底错误;右移丢的是最低位,只损失精度。
  • 易混:右移必须是算术右移(尾数为补码时补符号位),否则符号被破坏。

大数吃小数

  • 是:当两数相差超过 倍( 为有效位数)时,小数在加法中完全消失。 float 的 ,double 的 。
  • 易混:float a=1e8f; a+1.0f == a 成立。
  • 范围:由此得实用结论——求和一批浮点数时,从小到大加比从大到小加精度高得多。

左规 / 右规

  • 是:右规用于尾数溢出(),尾数右移 1 位、阶码 ;左规用于尾数最高位为 0,尾数左移 位、阶码 。
  • 不是:右规至多一次(两规格化数之和必小于 4);左规可能多次。
  • 易混:左规危险——它把低位的舍入误差左移到高位,两个相近的数相减会使有效位数急剧减少(抵消)。
  • 范围:右规还会使同一批尾数位代表的绝对精度翻倍(阶码 )。

舍入 (Rounding)

  • 是:IEEE 754 四种模式——就近舍入到偶(默认)、朝零、朝 、朝 。
  • 不是:默认不是”四舍五入”,正好在中间时取尾数末位为 0(偶)的那个。
  • 易混:取偶的理由是统计性的——一律逢中进位会使误差单向累积,取偶使误差期望为 0。
  • 范围:舍入发生在三处:对阶右移出的位、右规右移出的位、十进制常量在编译期转二进制时。所以 0.1f+0.2f != 0.3f 的误差在编译那一刻就已产生。

保护位 G / 舍入位 R / 粘滞位 S

  • 是:尾数末位之下多保留的三位。 是再往下所有位的”或”。
  • 不是:三位不是等价的——粘滞位专门用来区分”正好一半”和”略超过一半”。
  • 范围: 是正好一半(触发取偶); 且 或 为 1 则一定进位。没有粘滞位就无法实现就近舍入到偶。

浮点上溢 / 下溢

  • 是:浮点是否溢出只由阶码决定,与尾数无关。 阶码上溢 → ;阶码下溢 → 非规格化数,再小则 。
  • 不是:尾数溢出不是浮点溢出——它只触发一次右规,右规后阶码仍在范围内则结果完全正确。
  • 易混:上溢是真正的错误;下溢通常不视为错误,只是精度损失。

浮点运算的代数性质

  • 是:交换律成立()。
  • 不是:结合律、分配律都不成立;。反例:float 下 而 。
  • 范围:定点整数在不溢出时满足这些定律,浮点不满足——这是两者最重要的行为差异。

浮点乘除

  • 是:不需要对阶。乘法阶码相加、尾数相乘;除法阶码相减、尾数相除;之后同样规格化、舍入、判溢出。
  • 易混:阶码相加时偏置被加了两次,必须减去一个偏置:。这是浮点乘法题的固定陷阱。

2.3.3 C 语言中的浮点数类型

浮点类型与常量

  • 是:float 有效位 24(约 7 位十进制),double 有效位 53(约 15~16 位)。浮点常量默认是 double,3.14f 才是 float。
  • 不是:C 标准并不强制浮点必须是 IEEE 754(仅当定义了 __STDC_IEC_559__ 才承诺)。
  • 易混:float f = 3.14; 里 3.14 是 double,赋值时才被压成 float。
  • 范围:题目说”按 IEEE 754”就套;问”C 标准是否保证”,答”不保证”。 与整数那边”C23 前不强制补码”是同一类问题。

整数与浮点互转的四条路径

  • 是:int→double 精确(53 位 31 位);int→float 可能丢精度(有效位只有 24);float/double→int 向零截断、超范围是 UB;double→float 可能丢精度且可能溢出成 。
  • 不是:int 和 float 同为 32 位不代表互转无损——float 的 8 位给了阶码。
  • 易混:(int)(double)i == i 恒成立;(int)(float)i == i 不成立( 时)。(float)(double)f == f 成立;(double)(float)d == d 不成立。
  • 范围:int a=1,b=3; (float)(a/b) == 0.0f——除法在整型域就已截断,必须写 (float)a/b。

浮点比较

  • 是:== 不可靠,应比较差的绝对值。
  • 不是: 不能是固定常数——浮点误差是相对的,在 附近 double 的相邻值就差约 ,用 1e-9 等于用 ==。应取相对误差 。
  • 范围:两个例外可靠——精确表示的值之间(、小于 的整数);与 0 比较符号。

默认实参提升

  • 是:传给可变参数函数时 float 自动提升为 double。
  • 易混:printf 没有专门的 float 格式符,%f 一直是 double 的;而 scanf 必须区分 %f/%lf,因为指针不会被提升。

2.3.4 数据的大小端和对齐存储

大端 (Big-Endian) / 小端 (Little-Endian)

  • 是:大端 = 最高有效字节存在最低地址;小端 = 最低有效字节存在最低地址。 “端”指的是”哪一端放在低地址”。
  • 不是:四条否定——不改变位序;不改变寄存器里的数值;对单字节数据无影响;不改变数组元素之间的顺序。
  • 易混:0x12345678 存于 0x100:大端 12 34 56 78,小端 78 56 34 12。
  • 范围:大小端只在”一个多字节标量对象的内部”生效。因此字符串在两种机器上布局完全相同,文本协议无端序问题。

网络字节序

  • 是:TCP/IP 规定的大端。htons/htonl 在小端机上真的交换字节,在大端机上什么也不做。
  • 易混:x86/x86-64 是小端;ARM/RISC-V 可配置但实际几乎都是小端。
  • 范围:只有以字节流跨越机器边界时(网络、二进制文件、共享内存)端序才成为问题。

端序的判断方法

  • 是:int x=1; char *p=(char*)&x; if (*p==1) 小端;——取地址后按字节读,即位型重解释。
  • 不是:不能用 (char)x,那是值转换,两种机器上都得 1。

边界对齐 / 自然对齐

  • 是: 字节的数据,起始地址必须是 的整数倍。判断只看地址低几位是否为 0。
  • 不是:与大小端正交——两者互不决定。大小端由CPU 架构固定,对齐由编译器决定(可用 #pragma pack 改)。
  • 易混:不对齐的代价是访存次数增加(要访问两个存储字再拼接移位);早期 ARM、MIPS、SPARC 直接触发异常,x86 只是变慢。
  • 范围:本节的对齐粒度是字节,与操作系统内存管理的页/段(KB 级)层次不同、互不相干。唯一相似之处是”跨页要两次地址转换”与”跨存储字要两次访存”结构同构。

跨存储字的计算

  • 是:存储字长 、数据长 、起始地址 ,跨越的存储字数 ,等于访存次数。
  • 易混:、double()存于 : 次;对齐存放只需 2 次。

结构体填充 (Padding)

  • 是:编译器在成员之间插入填充字节以满足对齐;整个结构体的大小必须是”最大成员对齐要求”的整数倍。
  • 不是:尾部填充不是浪费——它保证数组中下一个元素的成员仍然对齐。
  • 易混:struct{char c; int i; short s;} 是 12 字节,struct{char c; short s; int i;} 是 8 字节。成员相同、顺序不同,大小差 50%。
  • 范围:按对齐要求从大到小排列成员,填充最少。 需要精确布局时(协议报文、文件格式、硬件寄存器映射)用 #pragma pack(1) 取消填充,代价是访问变慢或在某些架构上不可用。

高频范围限定清单

这张表集中列出本章最爱被抽掉限定条件的结论。 凡是记住了结论却忘了限定,考场上就会被反例打中。

结论必须加上的限定
”移位可以代替乘除 2”只对无符号数和非负数成立;有符号且不整除时 与 差 1
”补码取反加一得相反数”补 是例外,取反加一后仍是自身
”求补码就是取反加一”方法①的取反不含符号位,方法④(求相反数)包含符号位
”移码就是补码符号位取反”成立,但 IEEE 754 阶码的偏置是 ,不是
“阶码全 0 表示指数 “错。非规格化数的实际指数规定为 ,且隐藏位为 0
”最高位有进位就是溢出”只对无符号成立(CF);有符号看 (OF)
“同号相加会溢出”反过来才是有用的:异号相加绝不溢出
”浮点溢出看结果大小”只看阶码;尾数溢出靠右规修正,不算溢出
”尾数决定精度”是相对精度;绝对精度随数值量级变化
”浮点数满足加法交换律和结合律”只有交换律;结合律、分配律都不成立
”float 和 int 都是 32 位,互转无损”int→float 会丢精度(有效位仅 24);int→double 才精确
”强制类型转换是位型重解释”只在同宽度整数之间偶然成立;(int)f 是值转换
”看到 unsigned 就转无符号”要先做整数提升;int vs unsigned short 结果是有符号
”x >> k 是逻辑右移”无符号才强制逻辑右移;有符号是实现定义(实际为算术右移)
“移位量随便写”移位量 类型宽度是未定义行为
”除法溢出置 OF 后继续”除法是唯一会触发异常中断程序的定点运算
”除以 0 都会异常”整数除 0 异常;浮点除 0 得 ,不异常
” 就是 “只对容量成立;频率、带宽、传输率按
“大小端影响数据的存储顺序”只影响一个多字节标量内部;不影响数组元素顺序、char、位序
”对齐是编译器的事,与端序有关”两者正交,分别由编译器和 CPU 架构决定
”BCD 码要掌握”王道 2026 版第 2 章目录中已无该三级节

链接