編者:李國帥
qq:9611153 微信lgs9611153
2012-10-3
背景原因:
隨着時間的推移技術的更新,許多的知識在改變,但是人的想法未必跟着改變。
做這一行的人,未必一定要緊跟時代,但是卻不能有固步不前的想法。
問題描述及期望效果:
記得以前總是使用if(xxx==0.000001)判斷一個浮點數,這樣正確嗎?
所需資源:
VC
先看一下浮點數的實際大小:
內存跟蹤發現浮點數的真實大小是會發生變化的。
/*
fy1 0.020000000 float
fy2 1.9999999e-005 float
fy3 2.0000000e-006 float
fy4 2.0000000e-007 float
fy5 2.0000000e-010 float
dbly1 0.020000000000000000 double
dbly2 2.0000000000000002e-005 double
dbly3 1.9999999999999999e-006 double
dbly4 1.9999999999999999e-007 double
dbly5 2.0000000000000001e-010 double
fx1 0.0099999998 float
fx2 9.9999997e-006 float
fx3 1.0000000e-006 float
fx4 1.0000000e-007 float
fx5 1.0000000e-010 float
dblx1 0.010000000000000000 double
dblx2 1.0000000000000001e-005 double
dblx3 9.9999999999999995e-007 double
dblx4 9.9999999999999995e-008 double
dblx5 1.0000000000000000e-010 double
*/
比較分析:
進一步測試,發現自己對浮點數的理解是片面的,
真實的情況是:如果兩個非0數(a=1.0f和b=1.0f)進行比較的話,它們可能相同,也可能不同。
對於float,是將數據使用科學計數法表示之後,小數點後面的6位是正確的真實的,第7爲是進位之後的數據,不是精確數據。因此讓兩個float一定相等,前9個有效數字必須相等。
也就是說1.000000010f和1.000000019f是相等的,而0.0000001f和1.0000001f可能不相等。
對於double,是將數據使用科學計數法表示之後,小數點後面的14位是正確的真實的,第15爲是進位之後的數據,不是精確數據。因此讓兩個double一定相等,前17個有效數字必須相等。
/*
dblx0 1.2345678901234570e+18 double
dblx1 1.2345678901234568e+18 double
dblx2 1.2345678901234565e+18 double
dblx3 1.2345678901234565e+18 double
dblx4 1.2345678901234563e+18 double
dbly1 1.2345678901234563e+18 double
dbly2 1.2345678901234560e+18 double
fx0 1.23456794e+09 float
fx1 1.23456781e+09 float
fx2 1.23456781e+09 float
fx3 1.23456781e+09 float
fx4 1.23456781e+09 float
fy1 1.23456781e+09 float
fy2 1.23456781e+09 float
fx0 == fx1=0
fx0 == fx2=0
fx0 == fx3=0
fx0 == fx4=0
fx2 == fx1=1
fx3 == fx4=1
fy1 == fy2=1
dblx1 == dblx0=0
dblx2 == dblx0=0
dblx3 == dblx0=0
dblx4 == dblx0=0
dblx1 == dblx2=0
dblx3 == dblx4=0
dbly1 == dbly2=1
請按任意鍵繼續. . .
*/