從如何判斷浮點數是否等於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了,省的出錯。

相關文章
相關標籤/搜索