IEEE754 浮点数:简读+案例=秒懂
在IEEE 754 格式浮点数由 3 个部分组成,分别是 符号码,阶码,尾数码,对应部分所占位数如图 1-1 所示:
IEEE 754 标准分 3 个类型的浮点数:分别是 短浮点数 float,长浮点数 double,临时短浮点数 long double,下面的讨论一律采用 float 类型进行。
1. 关于 IEEE 754 浮点数标准中的阶码
在 IEEE 754 浮点数标准中,阶码是用移码表示的,移码的定义:移码 = 真值 + 偏置值;
1. 普通情况下,移码的偏置值为 2^(n-1), 8 位的移码的偏置值为 2^(8-1) = 128D = 1000 0000B;
例如:-127D = -0111 1111B , 其移码为 -0111 1111 + 1000 0000 = 0000 0001;
2. 在 IEEE 754 标准中,移码的偏置值是 2^(n-1)-1,8 位的移码的偏置值为 2^(8-1)-1 = 127D = 0111 1111B;
例如:-126D = -0111 1110B ,其移码为 -0111 1110 + 0111 1111 = 0000 0001
注意:8 位中,-127D 和 128D 这 2 个阶码有特殊用途,一般不在正常讨论范围(-126~127),他们的移码分别是:
- -127D:-0111 1111 + 0111 1111 = 0000 0000;
- 128D:1000 0000 + 0111 1111 = 1111 1111;
2. 关于 IEEE 754 浮点数标准中的尾数
在 IEEE 754 浮点数标准中,尾数码部分采用原码表示,且尾数码隐含了最高位 1,在计算时我们需要加上最高位1,即 1.M,我们通过一个例子来表示:
例如:有一个浮点数,真值为 0.11B ,那么其简略版的 IEEE 754 标准表示为(忽略 符号码 和 阶码):
即当 0.11B 这个数在记录为 IEEE 754 标准浮点数时,会这样处理,令 0.11 = 1.1 * 2^(-1) ,尾数码是 1.1000…,然后隐含最高位1,即 1 .1000…。
3. 计算 IEEE 754 标准浮点数的真值
在上述内容的分析之后,再通过观察分析以下这个 IEEE 754 单精度浮点数格式表示的数,系统性了解如何计算出 IEEE 754 标准浮点数的真值:
上数分别对应图1-1的中 S(符号码,0 正,1 负),E (阶码) ,M (尾数数值)为:
-
S (红色部分) :1
1,表示这个浮点数是个负数;
-
E (蓝色部分) :100 0000 1
100 0000 1,阶码,其真值为 :移码 - 偏置值 => 1000 0001 - 0111 1111 = 0000 0010 = 2D;
-
M (黑色部分) :010 0000 0000 0000 0000 0000
010 0000 0000 0000 0000 0000 表示这个浮点数的尾数部分,其真值为:被隐含的最高位1 + 0.尾数部分 => 1 + 0.01 = 1.01B;
通过对 S,E,M 的分析,我们可以计算出该浮点数的真值,即:
4. 十进制数转为 IEEE 754 浮点数格式
同样地再用一个例子 十进制数转为 IEEE 754 浮点数的例子,加深对 十进制数 与 IEEE 754 浮点数之间的转换的理解。
例如:将十进制数 -0.75 转为 IEEE 754 的单精度浮点数格式表示,分析过程如下:
-
S:1
-0.75 为负数,故 S 符号码为 1
-
E:0111 1110
由 过程A 得,阶码的真值为 -0000 0001 ,其移码为:-0000 0001 + 0111 1111 = 0111 1110
-
M:100 0000 0000 0000 0000 0000
由 过程A 得,尾数码真值为:-1.1,隐含最高位 1 ,取小数部分,得100 0000 0000 0000 0000 0000
最终结果为:
5. 关于IEEE 754 标准浮点数的范围
5.1. 最小绝对值
IEEE 754 单精度浮点型表示的的最小绝对值:尾数码全为 0 ,阶码真值为 -126D(对应的移码为 0000 0001B),此时整体的值为 1.0B * 2^(-126D)
5.2. 最大绝对值
IEEE 754 单精度浮点型表示的的最大绝对值:尾数码全为 1 ,阶码真值为 127D(对应的移码为 1111 1110B),此时整体的值为 1.111…B * 2^(127D)
5.3. 关于阶码真值为 -127 和 128
一般我们正常探讨的阶码区间是 -126D ~ 127D,而真值 -127D 的阶码为 0000 0000B,真值 128D 的阶码为 1111 1111B。
5.3.1. 阶码真值为 -127
- 当阶码全为 0 ,尾数不全为 0,表示 非规格化小数 ,用来表示比最小绝对值还要小的数,即
- 尾数码 隐含的最高位不是 1,而是 0;
- 阶码真值 固定为 -126,而非 -127;
- 当阶码全为 0 ,尾数全为 0,表示 真值 +/- 0 ;
5.3.2. 阶码真值为 128
-
当阶码全为 1 ,尾数全为 0,表示 正负无穷大 +/- ∞
-
当阶码全为 1 ,尾数不全为 0,表示非数值 NaN(Not a Number)
如 0/0,∞-∞ 等非法运算的结果即为 NaN
6. 补充
6.1. 关于数值后的字母
如 7.2D,1101 0001B:
7.2D 后面的字母 D 表示的是 Decimal(十进制),即表示 7.2 是个十进制数,7.2D 即为简写;
同样地,1101 0001B 后面的字母 B 表示的是 Binary(二进制),即表示 1101 0001 是个二进制数,1101 0001B 即为简写;
6.2. 关于十进制小数与二进制小数的转换
6.2.1. 十进制小数转为二进制小数
主要是小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0。例如十进制的0.125,要转换为二进制的小数,例如:
将 0.125D 转为 二进制数,步骤为:
-
0.125 * 2 = 0.25 => 取整数部分 0
-
0.25 * 2 = 0.5 => 取整数部分 0
-
0.5 * 2 = 1 => 取整数部分 1,结束。
结果为:0.001。
6.2.2. 二进制小数转为十进制小数
主要是乘以2的负次方,从小数点后开始,依次乘以2的负一次方,2的负二次方,2的负三次方等。例如二进制数0.001转换为十进制,例如:
将 0.001B 转为 十进制数,步骤为:
-
0 * 2^(-1) = 0
-
0 * 2^(-2) = 0
-
1 * 2^(-3) = 0.125
-
将 1,2,3 的结果加起来=> 0 + 0 + 0.125 = 0.125 ,结束。
结果为:0.125。