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


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

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

    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
            }
        }

    没错,很多经典的教科书或者指南,一些技术类的讲义,都会这样教授。但是为什么要这样写?

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

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

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

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

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

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

    经常说什么单精度一般小数点精度是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了,省的出错。

  • 相关阅读:
    [Audio processing] FFMPEG转音频格式和采样率
    [操作系统] OS X Yosemite U盘制作
    [基础] 广义线性回归
    [基础] 一些英文术语
    [经典] 在未排序数组中返回topK大的数
    [参数方法] 贝叶斯估计(待补充)
    [参数方法] 最小二乘
    [Theano] Theano初探
    font awesome的图标在WP8浏览器下无法显示的问题解决
    SQL 获取各表记录数的最快方法
  • 原文地址:https://www.cnblogs.com/coversky/p/7396280.html
Copyright © 2020-2023  润新知