IEEE754表示浮点数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IEEE754表示浮点数相关的知识,希望对你有一定的参考价值。
参考技术AIEEE754标准包含一组实数的二进制表示法。它有三部分组成:
三种精度的浮点数各个部分位数如下:
对于将某个实数表示为计算机浮点数,首先要将其 正规化 ,也就是表示为形如:
的样子。其中 b 是 0 或 1 ,而 p 二进制数表示的指数位。这样,假设想表示为单精度(float)的浮点数,那么:
上述中有一个词: 移码 (exponential bias)。因为指数 p 有正有负,那么在8位的指数位中我们就要拿出第一位来 指示符号 ,这样显然会造成不必要的浪费。给指数加上移码,就能保证结果 总是 一个非负数,也就可以将8个指数位都利用起来。对于有 M 个指数位的精度,其移码为:
这样就得到上面三种精度的移码:
通过此例可知,3.14的单精度浮点数表示是 0 1000-0000 1001-0001-1110-1011-1000-011 。现在我们来还原,看看它的误差:
利用二进制转十进制,可得它对应的十进制数是: 3.1400001049041748046875 。显然与3.14是有误差的。
我们再通过另一种方法估算误差。从例子中可知,对于3.14的单精度浮点数,我们舍去了第24位以及之后,它们是:
0.00... (23个0) ....00 [10001111.....]×2 1 b 。
为了方便计算,不妨假设此后全是0(即方括号中省略部分),也就是舍去了:
0.10001111b×2 -23 ×2 1 b
约为0.00000013317912817001;由于舍入进位关系,给第23位又加了1,所以加了:2 -23 ×2 1 ,故而要减去这一部分。
所以,误差约为2 -23 ×2 1 - 0.10001111b×2 -23 ×2 1 =0.00000010523945093155。所以结果大致为3.14+0.00000010523945093155= 3.14000010523945093155 。
可见和上面计算结果大致相同。
机器ε表示1与大于1的最小浮点数之差。不同精度定义的机器ε不同。以双精度为例,双精度表示的1是:
而比1大的最小双精度浮点数是:
从正规化中可知, 无论如何 浮点数都满足最左边是1。这就有一个严重问题:0没有办法被表示。为此,可以使用 非正规化 的表示方法,即让最左边默认为0,这样再另尾数也全部为0,就可以表示0了。
新的问题又来了: 根据什么 判断是非正规化还是正规化呢?
答案就是通过 指数部分 来反映。记得前面说过,双精度浮点数中, 指数加移码 的范围可以从0到2047,然而0和2047是作为他用的。在这里, 指数部分为0就代表着非正规化 。
所以,当见到指数部分为0是,尾数部分就不再是 1.bbbbb... 而是 0.bbbbb... 了。
再进一步,对于非正规化,可以看成是正规化中,小数点向 左边 跑了一位:1.bbbb....×2 -1023 =0.1bbbb....×2×2 -1023 ==0.1bbbb....×2 -1022 (只是概念上理解,小数第一位也不一定非要是1,如 0.001010×2^-1022 也可)。所以,非正规化下表示为:
现在,0就可以表示了。值得注意的是,此时0可以表示位+0和-0。
因为它的最左边不是1是0,实际上可以表示更小的数。双精度浮点数下,使用非正规化可以表示的 最小的正数 是0.00......01×2 -1022 也就是2 -52 ×2 -1022 = 2 -1074 。
请注意这个最小数和前面提到的机器ε的 区别 。比机器ε小的数是可以被表示出来的(利用非正规化)。但是当它们与其他浮点数做运算时,因为要转成同一种格式(正规化格式),从而可能会因为溢出位而被舍弃。最终结果就是,这些更小的数尽管能被表示,但是对运算结果没有影响。
上面说到,在双精度浮点数中,指数为0表示非正规化,那么指数为2047(二进制是111 1111 1111b,即11位指数位全为1)就表示无穷大和NaN(Not a Number)。具体表现在,当指数是2047,当尾数,全为0就表示无穷大,当尾数不全为0就表示NaN。
以52位尾数位的双精度浮点数为例,舍入时需要重点参考第53位:
由于存在这种舍入规则,浮点数一般在机器内都不会以原数精确相等的存储,这就会使在某些情况下,使用浮点数做算术运算时出现令人费解的情况,如在javascript中(数以双精度存储):
可见机器表示中,9.4-9-0.4 不严格等于 0,其结果有极小误差。因为按照上面的算法可知,9.4在机器内被表示为:9.4+0.2×2 -49 ,而0.4被表示为0.4+0.1×2 -52 。这样,当9.4-9时(因为9是整数是可以精确存储的)得0.4+0.2×2 -49 ,再减去0.4+0.1×2 -52 得3×2 -53 ,约等于"0.00000000000000033307"。
以上是关于IEEE754表示浮点数的主要内容,如果未能解决你的问题,请参考以下文章