1. 程式人生 > 其它 >Python二級——浮點型數值計算

Python二級——浮點型數值計算

技術標籤:計算機二級浮點數計算python

Python二級——浮點型數值計算

引言

​ 在python二級考試中,有這樣的題目:

print(0.1 + 0.2 == 0.3)

​ 答案是False

​ 對於初學計算機語言的人來說可能很奇怪,難道0.1+0.2不是等於0.3?當然也不是,但這就涉及到計算機語言的浮點型底層儲存


個位小數的加減法失真

​ 先編寫程式碼看看個位小數的加減法

for i in range(1,10):
    for m in range(1,i+1):
        a='0.{}'.format(i)
        b='0.{}'.format(m)
        c=
eval(a)+eval(b) print('{}+{}={}'.format(a,b,c),end=' ') print('') for i in range(2,10): for m in range(1,i): a='0.{}'.format(i) b='0.{}'.format(m) c=eval(a)-eval(b) print('{}-{}={}'.format(a,b,c),end=' ') print('')

輸出結果為
個位數加法

個位數減法

可以看到僅僅是個位小數的加減法,都有如此多的失真情況。

如果只是應對python的二級考試,只需要再編寫程式碼,將其中的失真的找出來就好了

for i in range(1,10):
    for m in range(1,i+1):
        a='0.{}'.format(i)
        b='0.{}'.format(m)
        c=eval(a)+eval(b)
        if c != round(c,1):
            print('{}+{}={}'.format(a,b,c))
    
for i in range(2,10):
    for m in range(1,i):
        a=
'0.{}'.format(i) b='0.{}'.format(m) c=eval(a)-eval(b) if c != round(c,1): print('{}-{}={}'.format(a,b,c))

執行結果:

0.2+0.1=0.30000000000000004
0.4+0.2=0.6000000000000001
0.6+0.3=0.8999999999999999
0.7+0.1=0.7999999999999999
0.7+0.2=0.8999999999999999
0.7+0.6=1.2999999999999998
0.8+0.4=1.2000000000000002
0.9+0.8=1.7000000000000002
0.3-0.1=0.19999999999999998
0.3-0.2=0.09999999999999998
0.4-0.1=0.30000000000000004
0.4-0.3=0.10000000000000003
0.5-0.4=0.09999999999999998
0.6-0.2=0.39999999999999997
0.6-0.4=0.19999999999999996
0.6-0.5=0.09999999999999998
0.7-0.2=0.49999999999999994
0.7-0.3=0.39999999999999997
0.7-0.4=0.29999999999999993
0.7-0.5=0.19999999999999996
0.7-0.6=0.09999999999999998
0.8-0.1=0.7000000000000001
0.8-0.2=0.6000000000000001
0.8-0.5=0.30000000000000004
0.8-0.6=0.20000000000000007
0.8-0.7=0.10000000000000009
0.9-0.3=0.6000000000000001
0.9-0.6=0.30000000000000004
0.9-0.7=0.20000000000000007
0.9-0.8=0.09999999999999998

​ 貌似有點多,這選擇題的一分,咋不要也罷,不過還是要記住幾個常見的加法失真的情況。


失真原因:float數值二進位制運算

​ 計算機是二進位制的資料,int型別進位制之間的轉化起來十分簡單與準確,但是float型別資料轉化為二進位制就比較麻煩。

  1. 浮點數儲存

浮點數在計算機中儲存也是以二進位制的形式,遵循IEEE二進位制算數標準;格式為:

float : 符號位(首位)、指數位(8位)、尾數(23位)

double:符號位(首位)、指數位(11位)、尾數(52位)

  1. 十進位制浮點數轉換為二進位制

★方法:

⑴整數部分:除以2,取出餘數,商繼續除以2,直到得到0為止,將取出的餘數逆序

⑵小數部分:乘以2,然後取出整數部分,將剩下的小數部分繼續乘以2,然後再取整數部分,一直取到小數部分為零為止。

如果永遠不為零,則按要求保留足夠位數的小數,最後一位做0舍1入。將取出的整數順序排列。

★示例:22.8125

⑴整數部分:除以2,商繼續除以2,得到0為止,將餘數逆序排列。

22 / 2 商11 餘 0

11 / 2 商5 餘 1

5 / 2 商2 餘 1

2 / 2 商1 餘 0

1 /2 商0 餘 1

得到22的二進位制是 : 10110

⑵小數部分:乘以2,取整,小數部分繼續乘以2,取整,得到小數部分0為止,將整數順序排列。

0.8125x2=1.625 取整1 小數部分是0.625

0.625x2=1.25 取整1 小數部分是0.25

0.25x2=0.5 取整0 小數部分是0.5

0.5x2=1.0 取整1 小數部分是0

得到0.8125的二進位制是 : 0.1101

⑶結果:十進位制:22.8125 等於二進位制: 10110.1101



由此可知,當浮點數化成的分數的分母部分是2的倍數時,才有可能完全精度轉化二進位制數,所以在計算的時候會出現失真情況。