浮点数表示误差详解

1. 存储结构

   计算机存储浮点数采用IEEE754标准,其结构为:

   

   数符s:0表示该数为正,1表示该数为负。占1bit大小。

   阶码e:采用移码表示,即加上了一个固定的偏移。阶码全为1表示无穷大。

   尾数f:尾数数值最高位1被隐藏,所以实际的尾数数值为1.f。在将数转为浮点数时,小数点左边也就必须是1的这种形式。

   真值的计算方法为:val = s * 1.f * 2e-offset

   

   float类型的最大数值为:1.111...11 X 2127 = 1.89045759400... * 1038

2. 浮点数表示产生误差原因

   a. 由于计算百机内部以二进制保存,所以十进制的有限位的小数,在计算机内部会是一个无限位的小数

      例如: 十进制的0.9虽然只有一位小数,转成2进制道是无限循环小数0.1110011001100110011...

   b. 计算机保存浮点数的精度有限,例如float可以保留十进制最多7位(二进制23位)有效数字,

      double可以保留十进制15-16位(二进制52位)有效数字。那有效数字以后的位就被忽略了。

      例如:0.9的表示受精度所限,精度以后的就被忽略了,这样

            float时,它是0.89999998

            double时,它是0.90000000000000002

   即:除了可以表示为2的幂次以及整数数乘的浮点数可以准确表示外,其余的数的值都是近似值。

3. 舍入方法

   既然十进制的有限位小数,在计算机内部可能是一个无限位小数,那就存在舍入策略。

   假定经过运算后的数共有p+q位,现仅允许保留前p位。舍入方法有许多种,常见的舍入方法有:

   a. 恒舍(切断):多余部分q位一律舍去,保留部分的p位不作任何改变。

   b. 恒置1法:即不论多余部分q位为何代码,都把保留部分p位的最低位置1。

   c. 下舍上入法:即0舍1入,相当于十进制中的四舍五入。用将要舍去的q位的最高位作为判断标志,以决定保留部分是否加1。

      如该位为0,则舍去整个q位(相当于恒舍)。如该位为1,则在保留的p位的最低位上加1。

4. 浮点数的比较

   浮点数比较的时候需要用一个很小的数值来进行比较。当二者之差小于这个很小的数时,就认为二者是相等的了。

   而不能直接用== 或!=比较。这个很小的数,称为精度。

   精度由计算过程中需求而定。比如一个常用的精度为1e-6.也就是0.000001.

   所以对于两个浮点数a,b,如果要比较大小,那么常常会设置一个精度。

   a. 判断等于的时候,就是:if(fabs(a-b) <= 1e-6)。fabs是求浮点数绝对值的函数。

   b. 判断大于的时候,就是:if(a > b && fabs(a-b) > 1e-6)

   c. 判断小于的时候,就是:if(a < b && fabs(a-b) > 1e-6)。

原文地址:https://www.cnblogs.com/yanghh/p/12915478.html