是什么

  • 定义:在 32 位机器中,数据类型的表示范围与精度由其底层结构决定。int 采用 32 位补码表示;float 采用 IEEE 754 单精度标准(1位符号位 + 8位阶码 + 23位尾数 )。

  • 大白话int 是个精确的“数数盒子”,但最大只能数到 31 个 1(正数上限);float 是个“科学计数法盒子”,能存极大极小的数,但有效精度只有 24 个 1,超过就会丢精度。

代码 f1(n) 就是公式 的 C 语言实现。只要没算爆(没发生溢出/丢精度),f1(n) 的数值就和公式 完全一致!

所以在答题和分析时,我们直接用 这个简洁的公式去推导,速度最快,也最不容易出错。

核心内容

1. IEEE 754 单精度浮点数(32位)如何计算

  • 存储结构

    \begin{array}{\|c\|c\|c\|} \hline \text{S (1位)} & \text{E 阶码 (8位)} & \text{M 尾数 (23位)} \\ \hline \end{array}

  • 十进制真值计算公式

    • 符号位 0 为正,1 为负。

    • 阶码 :移码表示(真实指数 )。

    • 尾数 :规格化数默认省去开头的 1.,只存小数点后的 23 位。有效精度为 位。

2. 十进制/二进制浮点数转 IEEE 754 机器数(三步法)

  1. 写成规格化二进制:如

  2. 提取

    • 真实指数 偏置阶码

    • 尾数 取小数点后 23 个 1

  3. 拼合十六进制

3. IEEE 754 特殊值速查

  • 阶码 (全 1),尾数 :表示 (如 7F800000H)。

  • 阶码 (全 1),尾数 :表示 (非数)。

4. 代码大题的“三板斧”破局法

  • 控制变量洞察unsigned 做减法(如 )必下溢变为 ,易引发死循环。

  • 精度对决 对应 个 1。

    • int 不溢出(最大

    • float 完全精确(最大

  • 溢出边界float 表示范围由阶码上限()决定,最大不溢出值满足 (最大 )。

例题

  • 题目:已知 。函数 f1int 计算,f2float 计算。

    1. 时,for(unsigned i=0; i<=n-1; i++) 为何死循环?

    2. f1(23)f2(23) 是否相等?求 f2(23) 的十六进制机器数。

    3. f1(31) 返回值为 ,为什么?使 f1(n) 结果正确的最大 是多少?

    4. f2(127) 机器数为 7F800000H,对应什么值?使 f2(n) 精确无舍入的最大 是多少?

  • 分析

    1. n - 1unsigned,下溢变成 i 在自增到 后溢出回 0,故 i <= n-1 永远成立。

    2. ,二进制有 24 个 1,正好填满 float 的 24 位有效精度,两者相等。

    3. ,二进制为 32 个 1(0xFFFFFFFF),在 int 补码中被解释为 int 最大的正数为 31 个 1,即

    4. 7F800000H 展开为 ,代表 。精确无舍入需

  • 答案

    1. n-1 下溢为 i 溢出回 0 循环无法终止。若改为 int0 <= -1 为假,不循环。

    2. 相等。f2(23) 机器数为 4BFFFFFFH

    3. 32 个 1 对应的 32 位补码真值为 。最大

    4. 值为 。结果精确的最大

⚠️ 易错点

Warning

  • 误以为 float 精度只有 23 位 IEEE 754 规格化数默认隐藏了整数位的 1.,有效精度是 23 + 1 = 24 位(可以精准存 24 个连续的 1)。

  • 阶码真值与移码混淆:移码 。如 中的指数是 ,代入得 ,不要忘记加偏置常数