Cruyun's Blog


Talk is cheap, show you my code


IEEE754浮点表示

浮点格式是一种数据结构,用于指定包含浮点数的字段、这些字段的布局及其算术解释。浮点存储格式指定如何将浮点格式存储在内存中。自计算机发明以来,曾出现许多中不同的浮点数表示方式,但目前最通用的是 IEEE 二进制浮点数算术标准(IEEE Standard for Binary Floating-Point Arithmetic, 简称IEEE 754 标准)。

IEEE 中的浮点数

IEEE 754 标准中定义了表示浮点数的四种格式:

  • 两种基本的浮点数: 单精确度(32 位字长) 和双精确度(64 位字长)。其中单精度格式具有24位有效数字,而双精度格式具有53 位有效数字,相对于十进制来说,分别是7位和16位有效数字。
  • 两种扩展的浮点数: 单精度扩展和双精度扩展。此标准并未规定扩展格式的精度和大小,但它指定了最小精度和大小: 单精度扩展需43 位字长以上,双精确度扩展需79位字长以上:(64位有效数字)。单精度扩展很少使用,而对于双精确度扩展,不同的机器构架中有不同的规定,有的为80 位字长(X86),有的为128 位字长(SPARC)。

浮点数格式

通常一个浮点数由符号 s 、指数 E 和尾数 M 组成,格式为

格式.png

  1. (-1)^s 表示符号位,当 s = 0,V 为正数;当 s = 1,V 为负数。
  2. M 是一个二进制小数,表示有效数字,大于等于1,小于2。
  3. 2^E 表示指数位。

十进制的 5.0,写成二进制是101.0,相当于1.01×2^2。那么,按照上面V的格式,可以得出s = 0,M = 1.01,E = 2。

十进制的-5.0,写成二进制是-101.0,相当于-1.01×2^2。那么,s=1,M=1.01,E=2。

我们从这个公式中可以分析出,阶码真值控制着小数点的位置,阶码每加1,整个数值增大2倍,小数点则向右移1位;阶码每减1,整个数值减小2倍,小数点则向左移动1位。

屏幕快照 2018-05-05 上午10.27.12.png

规格化的值

格式.png

  • 条件:阶码 exp不全为 0 且不全为1
  • 阶码采用偏移量移码:E = Exp - Bias
    • Exp: exp 字段的无符号数值
    • 偏移量Bias = 2 ^ (k-1) - 1,k 为阶码的位数
      • 单精度:127(Exp:1 ~ 254, E:-126 ~ 127)
      • 双精度:1023(Exp:1 ~ 2046, E:-1022 ~ 1023)
  • 尾数编码隐含先导数值1:M = 1.(frac)
    • frac = 0000…0(M = 1.0)时,为最小值
    • frac = 111…1(M = 2.0 - ε)时,为最大值

以单精度为例

单精度格式(32位)中的阶码为8位, 另有一位尾数的符号位S,处在最高位。

应该指出的是,浮点数的分数部分与有效位部分两者是不同的, 由于IEEE754标准约定在小数点左部有一位隐含位,从而使其有效位实际有24位,这样便使尾数的有效值变为1M。阶码部分采用移码表示, 移码值为127,从而使阶码值的范围由原来的1到254,经移码后变为-126到+127

单精度.jpg

非规格化的值

条件:阶码 exp 全为 0

  • 阶码值:E = 1 - Bias
  • 尾数编码隐含先导数值0:M = 0.(frac)

情况1:exp = 000..0, frac = 000.0

表示值0,根据符号位不同又有+0 和 -0之分

情况2:exp = 000..0, frac ≠ 000.0

特殊值

条件:exp = 1111..1

情况1:exp = 1111..1, frac = 000.0

表示无穷,根据符号位不同又有+∞-∞之分

情况2:exp = 1111..1, frac ≠ 000.0

不是一个数 Not A Number(NAN)

为什么阶码的偏移量是127?

机器零:

当浮点数的尾数为 0,不论其阶码为何值,或者当阶码的值遇到比它能表示的最小值还小时,不管其尾数为何值,计算机都把该浮点数看成零值,称为机器零。

当阶码 E 为全 0 且尾数 M 也为全 0 时,表示的真值 x 为零,结合符号位 S 为 0 或 1,有正零和负零之分。当阶码 E 为全1且尾数M 为全0时,表示的真值x 为无穷大,结合符号位S 为0或1,也有+∞-∞之分。这样在32位浮点数表示中,要除去E 用全0和全1(255)10表示零和无穷大的特殊情况,指数的偏移值不选128(10000000),而选127(01111111)。对于规格化浮点数,E 的范围变为1到254,真正的指数值e 则为-126到+127。因此32位浮点数表示的绝对值的范围是10 ^ (-38) ~ 10 ^ 38(以10的幂表示)——《计算机组成原理》

对于取127为偏移量的作用,有如下理解:

  1. 主要是为了让表示的范围能够对称起来

    分两种情况计算:

    • 偏移值为127时,绝对值范围大致是:1.210^(-38)~3.410^(+38);
    • 如果偏移值取为128时, 绝对值范围大致是:5.9 × 10^(-39) ~ 1.7 × 10^(+38);

    可见偏移值取127时,上下范围基本对称,相对合理点

  2. 除去非规格化、NaN和无穷大的数值

    如果选择偏移值128时,假设指数(不是阶码)为+127,按照e=E-128,则阶码为127+128=255,全为1 ,数值将为NaN和无穷大

    假设指数为0(包括正0和负0),按e=E-128,则正0+128=128,负0(补码)+128=0,可知E=0时,存在非规格化数

    由于8位E中,只有7位有效数字,7位能表示的大小为0-127,所以偏移量可以在0 ~ 127中任取一值,在IEEE754Z中规定取127.