對於標題疑問,2.25-2.2!=0.05,那正確答案是什麼呢?spa
print(2.25-2.2) //0.04999999999999982
事實證實,的確不等於0.05.那0.04999999999999982是怎麼得來的呢?
Google:由於偏差
偏差是怎麼產生的,爲何整數就能精確表示,而浮點數不能精確表示?
Google:由於整數和浮點數在計算機的存儲方式不一樣
那浮點數跟整數相比,浮點數在計算機如何存儲的呢?
Google:說來話長......code
1.計算機的本質
追根究底,計算機工做的實質即是電壓的高低切換,像電燈,高電位,電燈亮,低電位,電燈滅。爲了表示這兩種狀態,便引入0和1.爲了表示更多狀態,便增長0和1的對數。32bit和64bit的計算機就是這樣來的,表明了計算機內存存放待處理數據的大小。32bit的計算機內存大概在4G左右,64bit更多。圖片
//32bit 00000000000000000000000000000000-11111111111111111111111111111111
2.浮點數存儲方式
因爲計算機不識別十進制,因此十進制數據都要轉換爲二進制保存。而且是以二進制的科學記數法進行保存內存
2.25 = 10.01(二進制) = 1.001*2^1(二進制科學計數法) // 2.25整數部分轉換:2=10(除2取餘法) // 小數部分轉換過程:0.25*2 = 0.5 取整數部分0 (乘2取整法) // 0.5*2 = 1 取整數部分1 // 故小數部分0.25 = .01
浮點數轉換爲二進制科學計數法,由三部分組成符號位,指數位,尾數部分
it
這三部分在計算機中是怎麼存儲的呢?
以單精度float爲例,float根據IEEE R32.24標準數據佔32位,每部分存放規則以下:
class
說明:1.對於符號位,若值爲正,則爲0,若值爲負,則爲1
2.對於指數位,因爲指數存在正指數和負指數,佔一位,其他7位表示值的大小,故範圍爲-127~128.指數位採用移位存儲方式,即元指數+127(00000000=>-127)~(11111111=>128)
3.對於尾數部分,因爲第一位恆爲1,因此實際表示並未考慮第一位,因此有效位爲24位循環
那麼2.25(即1.001*2^1)在計算機中存儲方式爲:二進制
0(正) 10000000(1+127) 00100000000000000000000(.001)
2.2呢?
利用十進制轉二進制得:float
//2.2小數本分0.2採用乘2取整法過程: //0.2*2=0.4 0 //0.4*2=0.8 0 //0.8*2=1.6 1 //0.6*2=1.2 1 //0.2*2=0.4 0 //...... //不可能乘2剛好獲得1.0 2.2=10.00110011001100110011001100110011001100110011001101...(無限不循環) =1.00011001100110011001100*2^1(尾數部分超過23位都被截去了) !=2.2 0(正) 10000000(1+127) 00011001100110011001100
可見,2.2的小數部分經過乘二取整法,永遠沒法剛好達到1,因此二進制尾數部分紅無限不循環,超過23位的數據會直接被丟棄,致使與原十進制數據不相等。這也就是偏差產生的根源。im