python疑問2:2.25-2.2!=0.05?

對於標題疑問,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

相關文章
相關標籤/搜索