IEEE浮点数格式
在计算机中,浮点数的二进制编码是这样的,一个浮点数由三个部分组成:
(1) 1个符号位s;
(2) 若干位数,组成指数E;
(3) 若干位数,组成小数M.
然后浮点数的值等于 (-1)^s * M * 2^E。
比如32位的浮点数,指数域有8位,小数域23位;而64位的浮点数,指数域有11位,小数域有52位。
下面结合32位浮点数,说明一下指数E和小数M是怎么取值的。
这里先记指数域组成的无符号整数e = ek-1ek-2...e1e0,记小数域组成的二进制小数f = 0.fn-1fn-2...f1f0,记偏置值Bias = (2^(k-1) - 1)。
对于32位浮点数来说,Bias等于2^(8-1) - 1 = 127。
视指数域,分三种情况:
(1)指数域全是0:这样的浮点数叫非规格化数。E取值为1 - Bias, M取值为f.
例:[0 00000000 00000000000000000000000],是个非规格化数,符号位为正,E = 1 - 127 = -126, M = f = 二进制的0.00000000000000000000000 = 0,该值是0.
例:[0 00000000 01100000000000000000000],是个非规格化数,符号位为正,E = 1 - 127 = -126, M = f = 二进制的0.01100000000000000000000 = 十进制的0.375,则该数的值为0.375 * 2^(-126).
(2)指数域不全是0,也不全是1:这样的浮点数叫规格化数。E取值为e - Bias, M取值为1 + f.
例:[0 00000001 00000000000000000000000],是个规格化数,符号位为正,E = 1 - 127 = -126, M = 1 + f = 二进制的0.00000000000000000000000 = 1,则该数的值为1 * 2^(-126).
例:[1 11100000 11000000000000000000000],是个规格化数,符号位为负,E = 224 - 127 = 97, M = 1 + f = 1 + 二进制的0.11000000000000000000000 = 1 +十进制的0.75 = 1.75,则该数的值为-1.75 * 2^97.
例:[0 11111110 11111111111111111111111],是个规格化数,符号位为负,E = 254 - 127 = 127, M = 1 + f = 1 + 二进制的0.11111111111111111111111,则该数的值为(1 + 二进制的0.11111111111111111111111)* 2^127.
(3)指数域全是1: 这样的浮点数是特殊数值。
若小数域全是0,浮点值为无穷大(视符号位s分为正无穷大和负无穷大),即 [0 11111111 00000000000000000000000]是正无穷大, [1 11111111 00000000000000000000000]是负无穷大。
若小数域不全是0,浮点值为NaN(无效的数).比如 [ 0 11111111 00000000000000000000011]。
下图列举的是8位正浮点数的分布,从中可以看出浮点数取值的规律:
我对编码规则的一些理解:
(1) E的编码要e减去一个定值Bias,可使E能取负值又能取正值(原理类似于补码的编码,但最大、最小值不同);
(2) 非规格化数的E编码是1-Bias而不是-Bias,可确保非规格化数到规格化数之间的“连续性”;
(3) 规格化数M的编码,给f加上1,使M的取值限于[1,2),这样可提高指数域的位数。(原理类似于科学计数法中,有效数必须大于等于1小于10)
——读自《深入理解计算机系统》