【总结笔记】数据的表示与运算(C语言底层视角)

本部分涵盖:补码本质与转换、无符号数/有符号数类型转换、底层加减法流程、整数乘法与溢出判断、IEEE 754 浮点数表示与精度边界。


一、补码的本质——“观察滤镜”

核心思想:内存中的二进制位模式(Bit Pattern)永远不变,改变的只是编译器如何解读它。

滤镜(类型)最高位含义8 位表示范围
无符号(unsigned数值位,权重
有符号(int/char符号位,权重

补码最高位的负权重本质(以8位为例):

模平移公式 位):

  • 最高位为 0:有符号值 = 无符号值 (相同)
  • 最高位为 1:有符号值

二、补码转换四板斧

第一步:先看最高位!

最高位判断操作
0正数三码合一,直接加权求和,无需任何转换
1负数进入下面的转换流程

最高误区:看到补码就取反加 1!正数(最高位=0)绝对不要动!

负数补码的两种操作(严格区分)

目标操作方式符号位
求原码(写出机器数)符号位不动,数值位取反加 1保持 1
求真值(算十进制是负几)全部所有位取反加 1,得绝对值,补负号也取反

三种计算负数真值的方法(任选一种):

  1. 全位取反加 1:得绝对值,前面加负号
  2. 权重代入法:最高位乘 ,其余位正常加权
  3. 模公式(如

移位口诀

  • 左移(<<:不分正负,低位补 0;高位被截断可能溢出
  • 右移(>>
    • 无符号数(逻辑右移):高位补 0
    • 有符号数(算术右移):高位补符号位(正数补0,负数补1)

三、C语言整数类型混合运算——底层加减法

黄金法则绝对不要直接用十进制计算底层寄存器的内容!

解题标准流程(五步法)

Step 1:十进制 → 二进制补码(或十六进制)
Step 2:类型转换(赋值):位模式不变,只换解读方式
Step 3:减法 → 补码加法(A - B = A + (-B)的补码)
         求 -B 的补码:对 B 的补码全部取反加 1
Step 4:二进制补码加法,超出字长的进位直接丢弃(截断)
Step 5:根据结果变量的类型,将低 n 位翻译回十进制

溢出判断(三种方法,任写一种)

  1. 双符号位法:若两个符号位不同(01或10),则溢出(01正溢,10负溢)
  2. 进位异或法:最高有效位进位 与符号位进位 ,若 则溢出
  3. 符号逻辑法:正+正=负,或 负+负=正,则溢出

无符号数与有符号数的区别

  • 无符号数超字长:叫进位(Carry),不是溢出
  • 有符号数超范围:才叫溢出(Overflow)
  • **同一个加法器(ALU)**可以同时处理有符号和无符号运算,只需调整溢出检测逻辑

注意unsigned 做减法时若结果为负(如 unsigned i0-1),会下溢变成 (约 40 亿),极易导致死循环!


四、整数乘法的底层实现与溢出判断

实现原理:乘法 = 循环加法 + 移位(竖式乘法)

位 × 位 → 产生 位完整乘积(绝对不会溢出

溢出只发生在截断时

类型溢出判断依据
无符号乘法 位乘积的 位不全为 0 → 溢出
有符号乘法截断后符号位发生异常(正×正变负,负×负变正)→ 溢出

三种实现效率

方式速度原理
纯软件(加法+移位指令循环)最慢每步取指译码
带硬件支持的乘法指令中等微程序控制 ALU 自动循环
阵列乘法器最快纯组合逻辑,信号直通无需时钟

乘以 2 的幂次等价移位


五、IEEE 754 浮点数表示与精度边界

32 位单精度结构

真值计算公式

符号含义
符号位,0 为正,1 为负
移码(偏置阶码),真实指数
尾数,规格化数省略整数位 1.,实际精度为 23+1=24位
规格化尾数(默认整数位为 1,不存储)

特殊值速查

(阶码)(尾数)含义
全 0(全 0
全 0(非 0非规格化数(极小值)
全 1(全 0(如 7F800000H =
全 1(非 0NaN(非数,Not a Number)

十进制转 IEEE 754 三步法

  1. 写成规格化二进制:如
  2. 提取 23个1
  3. 拼合十六进制0 10010110 111111111111111111111114BFFFFFFH

精度与溢出边界( 类型题)

类型正常工作的最大 原因
int(32位)最大正数为 31 个 1(第 32 位是符号位)
float 精确无误差有效精度 24 位,
float 不溢出最大指数 ,需

易错:float 精度是 24 位不是 23 位!规格化数有隐含的整数位 1.,所以 23+1=24。


六、高频题型解题路线

题型一:求补码真值

看最高位
  → 0(正数):直接加权,三码合一
  → 1(负数):全位取反加 1 → 得绝对值 → 补负号
              或直接用模公式:S = U - 2ⁿ

题型二:C语言混合运算底层结果

转补码 → 类型转换只换解读不改位 → 减法变补码加法 → 截断低n位 → 按类型解读

题型三:乘法是否溢出

算出 2n 位完整乘积
无符号:高 n 位有非0 → 溢出
有符号:截断后符号位异常(正变负/负变正)→ 溢出

题型四:IEEE 754 边界判断(代码题)

f(n)有 n+1 个1
int:n+1 ≤ 31,即 n ≤ 30
float精确:n+1 ≤ 24,即 n ≤ 23
float不溢出:n+1 ≤ 127,即 n ≤ 126
7F800000H = +∞(阶码全1,尾数全0)

七、高频易错汇总

错误正确做法
正数也去取反加 1最高位为 0 → 正数,三码合一,直接加权
求原码和求真值搞混原码:符号位不动,数值位取反加 1;真值:全位取反加 1 求绝对值
直接用十进制算底层运算先转二进制补码,在二进制做完再截断,最后按类型解读
unsigned 做减法不考虑下溢0 - 1unsigned 变成 ,极易死循环
float 精度误以为 23 位规格化有隐含 1.,实际精度 23+1=24 位
阶码直接当指数真实指数 (要减偏置值)
以为 2n 位乘积会溢出2n 位中间结果永不溢出,溢出只发生在截断回 n 位时
有符号超范围叫进位有符号超范围叫溢出(Overflow);无符号超字长叫进位(Carry)