2_浮点数的规格化与非规格化表示

# 浮点数的规格化与非规格化表示

我们大概知道浮点数在计算机内要分成三个域来表示, 具体怎么个表示法, 就是浮点数的类型, 我们分成三个方面来讲

IEEE754 标准把浮点数分成三个类型

浮点数的类型

  • 规格化浮点数
  • 非规格化浮点数
  • 一些特殊值

规格化浮点数 (Normalized)

  • 满足条件

EXP 域既不能是全 0, 也不能是全 1

我们上节课说过, 浮点数 0101 存到硬盘的时候, EXP 会做一个简单的转换

就是真实的阶码值需要减去一个偏置量

阶码是什么 ? 请看上节的图片, 数字形式

这个很好理解啊 (才怪), 我们把这个数字存到计算机内部的时候是一个 0101 二进制串, 那么这个 0101 串可以表示一个无符号数, 完了这个无符号数要减去一个偏置量, 这个才是它最终真正表达的那个 e, 也就是阶码的值.

因为把 exp 看成一个无符号数值的话, 那么它就是一个大于等于 0 的数, 但是 e 这个值本身肯定有正有负, 所以要减去一个偏置量.

那么偏置量 (bias) 怎么去计算呢 ?

它是 2^(e-1) - 1.

(图片偏置量的计算)

然后是 frac 域, frac 域就针对我们刚才说的 `(-1)^s * (2^e) * M`, 就对应这个 M.

 这个公式也出现在上一节的图片中


M 一开始是多少呢, 就是应该是 1.xxx 这种形式, 我们说过它是一个表示 1.0 到 2.0 之间的一个数嘛, 左侧是闭区间. 为了提高表示的效率, 具体表示的时候, 只是取 M 小数点右侧的部分. 所以它最小表示为全 0, 实际上指 1.0; 那么最大就是全 1, 全 1 的真实数值实际上比 2.0 小一点点, 毕竟是开区间.

规格化浮点数示例

  • Float F = 15213.0

我们把它十进制的表示, 转换成二进制 :

15213 D = 11101101101101 B = 1.1101101101101 B * 2^13

这个结果我们把它分开来看 :

(这就对应了 图-数字形式 里面的公式)

  • 尾数 M = 1.1101101101101 B, 相当于它的有效数位就这些

刚刚说了, 如果它要存到硬盘里, 也就是表示为内部硬件的 frac 域的话, 小数点左侧的 1 是可以去掉的. 因为它是规格化的浮点数, 所以表示成 1101101101101 0000000000 B 这个形式, 后面的 0 是为了补齐, 因为它有 23 位.

  • 阶码 E = 13

那么我们要把阶码表示成为内部硬件表示的 exp 域的话, 应该加上它的一个偏置量 bias = 127

算出来 exp = 140 = 10001100 B

然后我们就集大成把下面的这一块整个地给它结合起来

Hex 466DB400
Binary 0100 0110 0110 1101 0100 0000 0000
140 100 0110 0
15213 *1*110 1101 1011 01

所以我们非常清楚地知道, 最终的二进制表示就是 : 第一位是 0, 0 就是它的符号位; 然后是阶码, 就是 100 0110 0; 再往后就是它的尾数, 尾数因为前导 1 已经去掉了, 所以就是后面那一串 110 1101 1011 01

非规格化浮点数 (Denormalized)

非规格化浮点数满足条件是 exp 为全 0.

E = - Bias + 1

Bias = 2^(e-1) - 1, e = exp 域的位数.

M = 0.xxxxxxx B, 小数点后面就是 frac 的比特数.

我们回想一下, 浮点数实质是什么. 比方说实数或者是整数, 要表示成 1.xxx 的这种形式, 然后乘上 2 的多少次方, **类似科学计数法**

但是如果这个 2 的多少次方, 这个特别小的话, 就是小到 2 的负多少多少次方都不够用了. 这种情况下这个 e 就不能变了, 因为 e 已经到头了最小了, 这时候我们要再去往小了表示, 就只能把小数点继续往左边移动. 这么往左边移动, 这个数的绝对值肯定变小了, 同时它数的精度是降低了.

所以它这个 M 就是 0 开头了.

具体示例

  • 0

exp = 0....0000, frac = 0....0000

exp 和 frac 都是 0, 那么这个就表示 0 了. 在浮点数表示里面, 有 +0 和 -0, 当然 +0 和 -0 实际上就差了一个符号位, 当然它们是相等的.

  • "非常接近" 于 0 的浮点数

exp = 000...0, frac != 0...0000

如果 exp 为全 0, frac 不等于全 0, 它就表示 "非常接近" 于 0 的浮点数.

就是这个值非常小了, 需要我们往左边移动小数点才能表示, 这就是逐步丧失精度.

一些特殊值

  • 满足条件

exp = 111...1

  • 具体示例

  exp = 111...1, frac = 000...0

  • - 表示无穷
  • - - 可用于表示数值的溢出
  • - - 有正无穷和负无穷
  • 例如 : 1.0/0.0 = +∞, -1.0/0.0 = -∞

  exp = 111...1, frac != 0000...0

  • 表示不是数的数 Not-a-Number (NaN), 就是说计算机上的数在数学上没办法表达
  • 例如 : √-1, ∞ - ∞, ∞ * 0