浮点数的表示方法

基本知识

定义

浮点数是一串 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 的问题
  • 处理比规格化数更小的数值

单精度浮点数的有效数字问题

举个栗子

  1. 将十进制数 8.125 转化为单精度的浮点数表示 8.125 的二进制表示为 1000.001 科学计数法表示为 \(1.000001*2^3\),对于该数,阶码实际值为 3,偏移之后的值为 \(3 + 127 = 130\),130转为二进制数为 10000010,尾数部分为 000001,首位符号位为0,得到其二进制表示为:
0 10000010 00000100000000000000000


注:尾数位不足23位则在后面补零,阶码不足8位则在前面补零,小数后面补零不影响小数的值,整数前面补零不会影响整数的值。

  1. 计算单精度浮点数所能表示的最大正整数
    当符号位为0,小数位全为 1,实际指数为 127 时,得到最大正值,可知最大正值为\(a=(1+ (1 - 2^{-23}))*2^{127}=3.4028234663852886*10^{38}\)

对我产生帮助的网站或文章

IEEE 754 浮点数标准在线浮点数计算转换十进制整数以及小数转二进制阶码全0和全1的浮点数