0.1+0.2=?在前端裡,告訴你:≠0.3 !

智雲程式設計發表於2019-05-12

今天,我來算一道"小學"數學題:0.1+0.2=?

0.1+0.2=?在前端裡,告訴你:≠0.3 !

按正常的數學邏輯來計算的話,0.1+0.2當然=0.3啦!但是,我們們也都不是什麼小孩子了,都走上了各行各業,那麼前端程式設計師要告訴你一個事!0.1+0.2≠0.3(手動滑稽)

我們們寫一段JS程式碼吧:

var a,b,sum;

a=0.1;

b=0.2;

sum=a+b;

執行結果:

image
image

WTF???

0.30000000000000004 是個什麼鬼?但這就是計算機給你正確的答案;

0.1+0.2=?在前端裡,告訴你:≠0.3 !

好吧,我來說說為什麼會出現這樣的結果;

首先宣告這不是bug,原因在與十進位制到二進位制的轉換導致的精度問題!其次這幾乎出現在很多的程式語言中:C、C++、Java、Javascript、Python中,準確的說:“使用了IEEE754浮點數格式”來儲存浮點型別(float 32,double 64)的任何程式語言都有這個問題!

0.1+0.2=?在前端裡,告訴你:≠0.3 !

簡要介紹下IEEE 754浮點格式:它用科學記數法以底數為2的小數來表示浮點數。IEEE浮點數(共32位)用1位表示數字符號,用8為表示指數,用23為來表示尾數(即小數部分)。此處指數用移碼儲存,尾數則是原碼(沒有符號位)。之所以用移碼是因為移碼的負數的符號位為0,這可以保證浮點數0的所有位都是0。雙精度浮點數(64位),使用1位符號位、11位指數位、52位尾數位來表示。

因為科學記數法有很多種方式來表示給定的數字,所以要規範化浮點數,以便用底數為2並且小數點左邊為1的小數來表示(注意是二進位制的,所以只要不為0則一定有一位為1),按照需要調節指數就可以得到所需的數字。例如:十進位制的1.25 => 二進位制的1.01 => 則儲存時指數為0、尾數為1.01、符號位為0.(十進位制轉二進位制)

回到開頭,為什麼“0.1+0.2=0.30000000000000004”?這是javascript語言計算的結果(注意Javascript的數字型別是以64位的IEEE 754格式儲存的)。

0.1+0.2=?在前端裡,告訴你:≠0.3 !

正如同十進位制無法精確表示1/3(0.33333…)一樣,二進位制也有無法精確表示的值。

例如1/10。64位浮點數情況下:

十進位制:0.1

二進位制:0.00011001100110011…(ps:一直迴圈0011)

尾數為1.1001100110011001100…1100(共52位,除了小數點左邊的1),指數為-4(二進位制移碼為00000000010),符號位為0

儲存為:0 00000000100 10011001100110011…11001

因為尾數最多52位,所以實際儲存的值為0.00011001100110011001100110011001100110011001100110011001

十進位制:0.2

二進位制:0.0011001100110011…(ps:一直迴圈0011)

尾數為1.1001100110011001100…1100(共52位,除了小數點左邊的1),指數為-3(二進位制移碼為00000000011),符號位為0

儲存為:0 00000000011 10011001100110011…11001

因為尾數最多52位,所以實際儲存的值為0.00110011001100110011001100110011001100110011001100110011

0.00011001100110011001100110011001100110011001100110011001

  • 0.00110011001100110011001100110011001100110011001100110011

= 0.01001100110011001100110011001100110011001100110011001100

轉換成10進位制之後得到:0.30000000000000004

0.1+0.2=?在前端裡,告訴你:≠0.3 !

自己是一名從事了5年開發的老程式設計師,業餘的時候在這裡分享一些經驗給大家

1.前端技術更新快,基礎類技術書籍很容易過時,大學裡的教材都還是5年前的版本,一本書從編寫到發行就要一年呢,學開發一定要學最新的技術哦。

2.很多時候跟著書和不繫統的影片學習,會發現沒有目標,學了很多卻不知道自己到底能夠做出什麼成績。要有一個清晰的職業學習規劃哦,畢竟你不是興趣愛好學著玩,是想要加入BAT等一線企業作職業開發工程師呢。

學習過程中會遇到很多問題,這時候去群裡問不一定有人回答你,百度也不知道百度什麼。本來可以2小時搞好的學習專案,結果搞了10個小時,慢慢會有挫敗感。一定要堅持下去!!!

web前端學習交流秋秋圈:767273102 ,每天會在裡面直播分享技術!根據這幾年從事前端的經驗,整理了一份最適合2019年學習的web前端乾貨,有想學習web前端的,或是轉行,或是大學生,還有工作中想提升自己能力的,歡迎大家加入,這裡是前端學習者的集中地


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2644068/,如需轉載,請註明出處,否則將追究法律責任。

相關文章