定点数和浮点数(三)

在前文中,说到了浮点数中的三个参数:S、E 和 M。其中的 S,只是代表正负号。浮点数的绝对值则由 E 和 M 决定。

E 和 M 共有 31 位二进制数,从全零开始逐步递增到全一,就能构成各种数字乃至非数字。
E 和 M 的变化,就在浮点数中,划分出来四个分类,如下所示。

浮点数的值与参数的关系是:N = (-1)^S × (隐含的整数位+M) × 2^(实际指数 e)
浮点数的值,是以 0 为对称点,在正负两个方向是对称的。
所以,下面只讨论正数的特点。负数的一方,就用正数镜像过去,也就一目了然了。
――――――――――――――――――――――――

一、非规约数
当 E = 0 时,称为非规约数。这是用来表示 0 以及在 0 附近的一些绝对值很小的数值。
在非规约数中,三个参数以及相关的数值如下。
  符号 S:0、1 皆可,即浮点数的数值是可正可负的。
  阶码 E:固定为 0,八位二进制即为 0000 0000。
    而实际指数 e,则固定为-126。
  尾数 M:尾数是【绝对值有效数字】中的 23 位小数,整数部分则是 0。 
    范围就是:0.000 0000 0000 0000 0000 0000 ~ 0.111 1111 1111 1111 1111 1111。
    其中的最高位(MSB),则代表 1 / 2、下一位则代表 1 / 4 ...;
    其中的最低位(LSB),则代表 1 / 2^23。
    由于【绝对值有效数字】中的整数部分固定为 0,于是就隐去了,以节省一个位。
因此,
非规约数所能表示的数值,就是:N = ± 0. M × 2^-126。

当尾数 M 为 0 时,应该就是最小值:N = (0. + 0) × 2^-126 = 0.0。
但是,专家们认为 0 是特殊规定的,并不叫最小值。只有当尾数为 1 时,才是最小值。
前面已经说过,尾数是 23 位小数,其最低位(LSB)为 1,就是:2^-23。
那么,
专家所说的最小值,就是:N = (0. + 2^-23) × 2^-126 = 2^-149。
拿计算器算一下吧,该数值是:1.4012984643248170709237295832899e-45。
这个数,真够小的!

以后,尾数可以加 1,再加 1、再再加 1、... ...。
非规约数所能表示最大值就是 M 为 23 个 1,如果再加 1,就成了整数 1。
因此,非规约数的
最大值就是:N = (1. - 2^-23) × 2^-126 ≈ 1 × 2^-126。
拿计算器算一下吧,这个数值是:1.1754943508222875079687365372222e-38。
从 0 开始,加到这个最大值,共有 2^23 = 8,388,608 个数值!
数与数之间的间隔,都是 2^-129 !
真够密集的!

结合符号位S,非规约数的范围就是:-1 × 2^-126  <  N  <  +1 × 2^-126。
把非规约数画在数轴上,就是下图中绿色的部分:

二、规约数
非规约数最大值的 M 中,再加上 1(即 2^-23),就进入了规约数的范围。
在规约数中,三个参数以及相关的数值如下。
  符号 S:仍然是 0、1 皆可,即数值仍然是可正可负的。
  阶码 E:E 是变化的,范围为 1~254,八位二进制即为 0000 0001~1111 1110。
      而实际指数 e 则为 E-127,范围就是-126 ~+127。
  尾数 M:尾数仍然是【绝对值有效数字】中的 23 位小数。
    在规约数中,隐含的【有效数字】的整数部分则是 1。
因此,
规约数所表示的数值是:N = ± 1. M × 2^(-126 ~ +127)。
式中的整数部分 1.,是在浮点数中隐含的。在浮点数中,它并不出现。

由于 E 值的范围较大,所以,规约数的表达范围,就比非规约数的范围大得多了。
因此,平时所见的浮点数,绝大多数都是规约数。

当 E 为最小值 1 (此时的实际指数 e = E -127 = -126),M 为最小值 0,即可构成规约数的最小值,即:N = (1. + 0) × 2^-126。
拿计算器算一下吧,这个数值,也是:1.1754943508222875079687365372222e-38。
此值虽然与
非规约数最大值的近似值相同,但是,它们之间,还是相差了 2^-149。
所以,从
非规约数过渡到规约数,并没有任何的突兀,完全是 “平滑” 过渡过来的。

此后,M 可以继续递增,到了最大值再加一,M 又从 0 开始,而阶码 E 将加一 。
当 E = 2 时,实际指数 e 就是-125了。
此时,数值与数值之间的间距,就是 2^-23 × 2^-125 = 2^-148,比之前的间距提高了一倍。

以后,都是这样发展,每当 E 增加1,各数值之间的间距,就会增加一倍。
按照这种变化规律,由 E 控制的间距,就是等比级数(也称为几何级数),公比是 2。

直到 E = 254、M = 2-2^-23,就形成了规约数的最大值:N = (2-2^-23) × 2^127。
拿计算器算一下吧,这个数值是:3.4028236692093846346337460743177e+38。

把规约数画在数轴上,可见下图中橙黄色的区域:

三、无穷大
在规约数最大值时,M 再加一,就形成了:E = 255 = 1111 1111B、M = 0
此种状态,就是浮点数的无穷大表示。

四、NaN
在 “无穷大” 时,M 再加一,就是 E = 255、M > 0。这种状态,就代表了 NaN (非数字)。
如果你遇到了除数为 0 的算式,你就可以用 NaN 来表达运算结果。

综合以上所述,小结一下吧。

单精度浮点数由 32 位二进制数组成,包括 1 位符号,8 位阶码,23 位尾数。
阶码:用移码表示,偏置为 126 (非规约数)和 127 (规约数)。
   实际指数 e 的范围则是:-126 ~ +127。
尾数:有效数字实际有 24 位。一位整数固定为 0(或 1),于是就隐含了,以节约一个位。
   尾数中只保存 23 位小数。

浮点数的表示范围,主要由阶码来控制,为:-2^128 ~ +2^128 (十进制则是 -3.40E+38 ~ +3.40E+38)。
浮点数的表示精度,则由 1 位整数和 23 位尾数共同来控制:2^24 = 16,777,216。

关于浮点数的精度问题

1 位整数和 23 位的小数(尾数),共有 24 位二进制数,换算到十进制,就是 8 位十进制数。
对应关系如下。
最小:0.000 0000 0000 0000 0000 0000 (二进制) = 00,000,000 (十进制);
最大:1.111  1111  1111  1111  1111  1111 (二进制) = 16,777,215 (十进制)。

在二进制变化的过程中,十进制也随之变化。但是,只有低 7 位数的变化范围是从 0 到 9,可以说是“完整的变化”。而最高位,只是从 0 变到 1,在 0~9 的完整范围中,最高位只变化了 0.2 。这就是说:在十进制数中,只有 7.2 位,对应于 24 位二进制数。

十进制数的有效位数 m,如果用数学公式来求证,就是:

   10^m = 2^24, m = log10 (2^24) = 7.2 ≈ 7 位。

即:32 位浮点数,如果用十进制表示有效数字,只有 7 位是准确的。位数再多了,就不准了。
因此,用 C 语言输出 32 位浮点数变量的值,默认时,它只给你输出 6 位十进制数。它这么做,就是为了保证精度。

因为尾数只有 23 位,所以,当你在 C 中对变量的赋值,超出 7 位十进制数时,编译系统就会将其截短后再存放。如果你再用这种浮点数变量,做比较大小等操作,就有可能出现不符合原值的某些结果。

另外,双精度浮点数有 64 位,含有 1 位符号,11 位阶码,52 位尾数。
阶码:用移码表示,偏置为 1022 或 1023。
   实际指数的范围为:-1022 ~+1023。
尾数:实际有 53 位,隐含了整数后,尾数中只出现 52 位小数。
由阶码控制表示范围:-2^1024 ~ +2^1024 (十进制是 -1.79E+308 ~ +1.79E+308)。
由尾数控制表示精度:2^53 = 9,007,199,254,740,992。
这是 16 位十进制数,可保证精度的是 15.9 位。

本文完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值