浮点数的运算精度丢失
引出
打開Python編譯器,輸入 0.1+0.2, 期待的結果是0.3,但是輸出為:
0.30000000000000004
有點小尷尬,這是為什么呢?
解惑
其實這設計到了計算機的浮點數存儲是以二進制進行存儲的。
說二進制不太形象,換成我們最長使用的十進制和分數
1/5,使用小數表示為0.2,但是1/3,使用小數表示就是一個無限循環小數:0.3333333, 也就是說,分數的 1/3+1/3=2/3,但如果使用小數:0.3333+0.3333=0.6666, 結果只會無限接近2/3,而不會等于2/3
因為把10分成三份,是不能夠整分的。同樣,把2分成十份,也不能整分??紤]到2整分只能分成兩份,也就是說,二進制只能精確表示十進制小數0.5
十進制到二進制的轉換在此略過。
十進制的0.1,轉換成二進制是:0.00011001100110011無限循環的小數,所以二進制的小數運算,就會出現上面的1/3+1/3的情況,無法精確計算,只能夠近似表示。那為什么python這些語言,我們在使用的時候沒有察覺到這個問題呢?因為編譯器自覺的幫我們做了近似的處理。
和十進制無法精確表示分數的1/3同樣,二進制也無法精確表示十進制的小數。
分析
為了方便分析,我們講計算機存儲的字節數量進行縮減,我們假設小數點后只能保存8為小數。
十進制的0.1,轉換成二進制為:0.00011001 (再反轉回十進制,就會發現精度的丟失了,十進制是:0.09765625)
十進制的0.2,轉換成二進制為:0.00110011 (反轉回十進制,為:0.19921875)
加法運算:
十進制
0.1+0.2=0.3
二進制
0.00011001+0.00110011=0.01001100 (轉成十進制:0.296875)
當然,計算機中存儲的位數要比8位多,python浮點數占用8個字節,64位。但因為是無限小數,并不是位數多了就會準確。
那么如何做這種精度的計算呢?其實很簡單,精度丟失是小數才會有,只要轉成整數,就不會有這個問題了。比如Python中:
(1.0+2.0)/10
結果:0.3, 沒毛病。
當然,這個0.3也不是精確的0.3,但會在顯示過程進行精度轉換,通過整數運算,避免了小數運算過程中的丟失精度問題。
總結
以上是生活随笔為你收集整理的浮点数的运算精度丢失的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不知道写的是啥
- 下一篇: 2016-2017NBU期末考试记录