前言
本文按照以下顺序讲解:
- 浮点数
- IEEE 754定义的浮点数表示法
- float 的最大值分析
- 题目分析
浮点数
任何一个10进制数 N 都可以表示为
N = X * 10^Z
比如:
25 = 2.5 * 10^1
456.998 = 4.56998 * 10^2
其中 X 被称为尾数,Z 被称为阶码,这里的10 是底数。
尾数的长度决定了浮点数的精度。
阶码决定了小数点在数据中的位置。(之所以被称为浮点数的原因)
根据惯例,10进制时底数取10,2进制时取2。
IEEE 754 定义的浮点数
IEEE 754 规定了计算机中32位浮点数和64位浮点数的表示方法。我们先看一下32位浮点数在内存中的结构分布:

根据规定:
- 最高位表示数据的符号:0表示正数,1表示负数
- 最低位23位表示尾数,并且在还原回真正浮点数尾数时应为
1.x
- 中间8位表示阶码,使用移码表示
- 规定底数为2
以下图为例:

我们首先看到,它的符号位为1,因此表示的数据时负数。阶码为移码00001011,换算成源码为:
00001011(移) = 10001011(补) = 10001010(反) = 11110101(原) = -117
不过,这里一定要注意到第2条规定,即尾数部分隐含了最前面整数的1,因此,阶码应当作出修正来适应隐藏操作,即阶码需要加1,所以,最终的阶码应当为-116。
我们再来分析尾数,从表中可以看出,尾数是1010.....,根据第二条规定,我们可以得到真实的尾数为二进制的1.1010,十进制的1.625。
所以表中表示的数字为:
-1.625*2^-116
float 所能表示的范围
首先,尾数占23位,它的范围为 1 ~ 2 之间
阶码是8位整数,范围为 0 ~ 255 之间,不过IEEE 754 保留了其中的0和255作为特殊值使用,且要减去127才是真正的阶码值,所以阶码值得范围为 -126 ~ 127。所以 float 所能表示的范围为 (2-2(-23))*2127。
数学例题分析
问题:将十进制数 16.59375 转换为符合 IEEE 754 格式的 32 位浮点数来存储。
解答:
- 将16.59375 转换成二进制:
<1> 16 = 0b10000
<2> 0.59375 * 2 = 1.1875 -----> 1
0.1875 * 2 = 0.375 -------> 0
0.375 * 2 = 0.75 ---------> 0
0.75 * 2 = 1.5 -----------> 1
0.5 * 2 = 1 --------------> 1
0.59375 = 0b0.10011
<3> 16.59375 = 0b10000.10011
- 将真实值 10000.10011 规范为以2为底的科学计数法:
10000.10011 = 1.000010011*2^4 - 阶码规范为127偏移值的移码方式表示:
4 + 127 = 131 = 0b10000011 - 因为原值是正数,所以符号位为 0
-
最终得到 16.59375 的 32位浮点型内存存储结构为下图所示:
32位浮点数内存结构图
网友评论