从如何判断浮点数是否等于0提及——浮点数的机器级表示(转)

http://www.cnblogs.com/kubixuesheng/p/4107309.htmlhtml

这位前辈讲的不错,摘抄下来以表尊敬!编码

void isZero(double d)
    {
        if (d >= -DBL_EPSILON && d <= DBL_EPSILON)
        {
            //d是0处理
        }
    }

    void isZero(int d)
    {
        if (0 == d)
        {
            //d是0处理
        }
    }

    void isZero(int *d)
    {
        if (NULL == d)
        {
            //d是空指针处理
        }
    }

    void isZero(bool d)
    {
        if (!d)
        {
            //d就认为是false 也就是0
        }
    }

没错,不少经典的教科书或者指南,一些技术类的讲义,都会这样教授。可是为何要这样写?spa

可能一部分人就糊涂了,不知道咋回答,搞技术或者作学问不是诗词歌赋,结论经不起严谨的推敲就不能服众,不能够说,书上是这样写的,或者老师告诉个人,那样太low了。尤为是浮点数比较的问题,不仅是0,相似的和其余的浮点数比较大小的问题也是同样的。操作系统

要解决这个疑惑,必须先理解计算机是如何表示和存储浮点数据的,期间参考了IEEE单双精度的规范文档,和MSDN的一些文档,以及《深刻理解计算机操做系统》一书。指针

这样的结果在不一样机器或者编译器下,有可能不一样,可是能说明一个问题,浮点数的比较,不能简单的使用==,而科学的作法是依靠EPISILON,这个比较小的正数(英文单词episilon的中文解释)。code

EPSILON被规定为是最小偏差,换句话说就是使得EPSILON+1.0不等于1.0的最小的正数,也就是若是正数d小于EPISILON,那么d和1.0相加,计算机就认为仍是等于1.0,这个EPISILON是变和不变的临界值。htm

#define DBL_EPSILON      2.2204460492503131E-16 
2 #define FLT_EPSILON     1.19209290E-07F 
3 #define LDBL_EPSILON     1.084202172485504E-19 

浮点数表达的有效位数(也就是俗称的精度)和表达范围不是一个意思blog

常常说什么单精度通常小数点精度是7-8位,双精度是15-16位,到低怎么来的呢?前面说了,单精度数尾数23位,加上默认的小数点前的1位1,2^(23+1) = 16777216。关键: 10^7 < 16777216 < 10^8,因此说单精度浮点数的有效位数是7-8位,这个7-8位说的是十进制下的,而咱们前面说的尾数位数那是二进制下的,须要转换。文档

又看,双精度的尾数52位存储,2^(52+1) = 9007199254740992,那么有10^16 < 9007199254740992 < 10^17,因此双精度的有效位数是16-17位。编译器

貌似实际编码中,大部分直接用double了,省的出错。

相关文章
相关标签/搜索