IEEE 754浮点数表示法
IEEE 754是最常用的浮点数表示法,在使用浮点数前必须对其原理有详细的了解才可以写出没有精度损失而且安全的代码。
IEEE 754规定了浮点数的基本结构:符号(sign),偏移的指数(biased exponent),有效段(significand field)
| 精度名 | 宽度 | 指数段 | 有效段 | 指数范围 | 指数偏移 | 精度 |
|---|---|---|---|---|---|---|
| float | 32位 | 8位 | 23位 | [-126, 127] | +127 | 7 |
| double | 64位 | 11位 | 52位 | [-1022, 1023] | +1023 | 16 |
以32位单精度浮点数为例,其偏移的指数有8位,因此偏移为28-1 = 128 - 1 = 127,因此偏移值为127时,指数实际为0。这使得同时规定偏移值为0和255时,分别代表一些特殊情况,实际上指数的取值为 [-126, 127]。
IEEE 754浮点数包括规格形式和非规格形式:
由于二进制表示下,一个位要么是0要么是1,所以为了使得相同值的浮点数有唯一的二进制表示,所以规定指数取值要满足整数部分是1,此时为规格形式。
即11112 表示为1.1112 * 2 3。
同时由于规格形式的有效数的整数部分必是1,所以实际上可以去除首位的1,即只储存小数部分,同时左移到高位,低位补0。
当偏移的指数为0时,则此时为非规格形式浮点数:
非规格形式的浮点数表示0和接近0的数,由于我们在规格形式中隐藏掉了整数位的1,所以规格形式的全0代表1 * 2-127,但显然不能让他这么代表,因此规定此时为非规格形式,且并隐含的整数位为0,且指数固定为 -126。
规格数中最接近0的数是0 00000001 00000000000000000000000,即1 * 2-126,非规格数最接近此数的数为0 00000000 11111111111111111111111即0.111111111111111111111111 * 2-126。
因此,非规格数中最大的数是在有限小数位下最接近规格数最小正数的数。
因此,非规格数从这个最大数开始,可以逐渐递减到0。
除了非规格数,还有两个特殊数:
无穷(Infinity):偏移的指数全1,有效数全0。
不是数(Not a Number):偏移的指数全1,有效数不为0。
IEEE 754还规定了浮点数的计算方式:
加法:
- 补全隐藏的整数位
- 将小数的指数对齐到大数的指数
- 对有效数进行加减运算
- 规格化,若溢出则将有效数清零