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了,省的出錯。