是什么
-
定义:在 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 机器数(三步法)
-
写成规格化二进制:如 。
-
提取 :
-
-
真实指数 偏置阶码
-
尾数 取小数点后 23 个
1
-
-
拼合十六进制:。
3. IEEE 754 特殊值速查
-
阶码 (全 1),尾数 :表示 (如
7F800000H为 )。 -
阶码 (全 1),尾数 :表示 (非数)。
4. 代码大题的“三板斧”破局法
-
控制变量洞察:
unsigned做减法(如 )必下溢变为 ,易引发死循环。 -
精度对决: 对应 个 1。
-
int不溢出(最大 ) -
float完全精确(最大 )
-
-
溢出边界:
float表示范围由阶码上限()决定,最大不溢出值满足 (最大 )。
例题
-
题目:已知 。函数
f1用int计算,f2用float计算。-
当 时,
for(unsigned i=0; i<=n-1; i++)为何死循环? -
f1(23)与f2(23)是否相等?求f2(23)的十六进制机器数。 -
f1(31)返回值为 ,为什么?使f1(n)结果正确的最大 是多少? -
f2(127)机器数为7F800000H,对应什么值?使f2(n)精确无舍入的最大 是多少?
-
-
分析:
-
时
n - 1为unsigned,下溢变成 。i在自增到 后溢出回0,故i <= n-1永远成立。 -
,二进制有 24 个 1,正好填满
float的 24 位有效精度,两者相等。 -
,二进制为 32 个 1(
0xFFFFFFFF),在int补码中被解释为 。int最大的正数为 31 个 1,即 。 -
7F800000H展开为 ,代表 。精确无舍入需 。
-
-
答案:
-
n-1下溢为 ,i溢出回 0 循环无法终止。若改为int,0 <= -1为假,不循环。 -
相等。
f2(23)机器数为4BFFFFFFH。 -
32 个 1 对应的 32 位补码真值为 。最大 。
-
值为 。结果精确的最大 。
-
⚠️ 易错点
Warning
误以为
float精度只有 23 位 IEEE 754 规格化数默认隐藏了整数位的1.,有效精度是 23 + 1 = 24 位(可以精准存 24 个连续的 1)。阶码真值与移码混淆:移码 。如 中的指数是 ,代入得 ,不要忘记加偏置常数 。