浮点数的表示方法
基本知识
定义
浮点数是一串 0 和 1 构成的位序列(bit sequence),从逻辑上用三元组{\(S\),\(E\),\(M\)}表示任意的实数 \(𝑋\) 可如下表示:
\[𝑋=(−1)^𝑆∗𝑀∗𝑅^𝐸 \]
注意:IEEE 中浮点数的尾数 \(𝑀\) 中仅记录了小数位(默认省略了整数位1),所以上述公式中的 \(𝑀\) 实际值为 \(𝑀+1\),另外由于该实数使用二进制表示,所以基数 \(𝑅\) 为 2
综上所述,在 IEEE 754 标准的前提下,任意一个实数 \(𝑋\),可表示为如下的形式
\[𝑋=(−1)^𝑆∗(1+𝑀)∗2^𝐸 \]
类型
数符(S) | 阶码(E) | 尾数(M) | 总位数 | 偏移值 | |
短实数(Float) | 1位 | 8位 | 23位 | 32位 | 127 |
长实数(Double) | 1位 | 11 位 | 52位 | 64位 | 1023 |
临时实数 | 1位 | 15位 | 64位 | 80位 | 16383 |
关键字 (什么叫做 数符,阶码,尾数)
- 数符:符号位,0正1负
- 阶码:科学计数法中的指数部分(补码表示)
- 尾数:科学计数法中的尾数部分(即小数点后面的部分。因为小数点前面的整数部分仅可能是1,可以将这个1忽略掉以减少不必要的存储空间)
关于 float 类型阶码偏移值为什么是 127 而不是 128 的解释
- 预备知识
阶码在浮点数中占 8 位,对于 8 位的有符号整数,其补码可表示的范围为:[-128, 127],但为了方便比较直接比较阶码的大小,会将实际值偏移固定数值,使得存储值均为非负整数,于是目的为存储 8 位的有符号整数便改为了存储 8 位无符号整数,其补码可表示的范围为:[0, 255],IEEE 754 的规定:若阶码全为 0 或全 1 要进行特殊处理,所以 [0, 255] 中的数值 0 和 255 被排除,剩下的无符号数字范围为:[1, 254],为了可表示的正数和负数范围均衡,IEEE 754 设置移码为 127,则实际可表示的指数范围为:[-126, 127] - 疑问解答
若设置偏移值为 128,指数的实际范围为 [-127, 126],也能达到正负数均衡的要求,但:
移码为 127 与 128 相比多表示的指数是 +127,而少表示的指数是 -127,实际生活中 \(1.x∗2^{127}\) (\(x\) 表示任意数量的任意数字) 远比 \(1.x∗2^{-127}\)
阶码全0和全1
- 阶码全为 0 (非规格化数)
- 尾数为0,则表示该数为 +0或-0,符号由符号位决定
- 尾数非0,此时隐藏的整数位不再是1,而是零,此时可用于表示比规格化数更小的数
- 阶码全为 1
- 尾数为0,则表示该数为 \(+\infty\)或\(-\infty\),符号由符号位决定
- 尾数非0,这样的数称之为 NaN (Not a Number), 1/0的结果就是一个典型的 NaN
- 非规格化数
- 在上文中我们说到,浮点数默认隐藏的整数位为1,在这种情况下怎样表示 0 呢,很明显无法表示,所以这里引出非规格化数来处理。非规格化的数的两个作用为:
- 处理 0 的问题
- 处理比规格化数更小的数值
单精度浮点数的有效数字问题
举个栗子
- 将十进制数 8.125 转化为单精度的浮点数表示 8.125 的二进制表示为 1000.001 科学计数法表示为 \(1.000001*2^3\),对于该数,阶码实际值为 3,偏移之后的值为 \(3 + 127 = 130\),130转为二进制数为 10000010,尾数部分为 000001,首位符号位为0,得到其二进制表示为:
0 10000010 00000100000000000000000
注:尾数位不足23位则在后面补零,阶码不足8位则在前面补零,小数后面补零不影响小数的值,整数前面补零不会影响整数的值。
- 计算单精度浮点数所能表示的最大正整数
当符号位为0,小数位全为 1,实际指数为 127 时,得到最大正值,可知最大正值为\(a=(1+ (1 - 2^{-23}))*2^{127}=3.4028234663852886*10^{38}\)
对我产生帮助的网站或文章