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;
執行結果:
WTF???
0.30000000000000004是個什麽鬼?但這就是計算機給你正確的答案;
好吧,我來說說為什麽會出現這樣的結果;
首先聲明這不是bug,原因在與十進制到二進制的轉換導致的精度問題!其次這幾乎出現在很多的編程語言中:C、C++、Java、Javascript、Python中,準確的說:“使用了IEEE754浮點數格式”來存儲浮點類型(float 32,double 64)的任何編程語言都有這個問題!
簡要介紹下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格式存儲的)。
正如同十進制無法精確表示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
自己是一名從事了6年開發的老程序員,業余的時候在這裏分享一些經驗給大家
1.前端技術更新快,基礎類技術書籍很容易過時,大學裏的教材都還是5年前的版本,一本書從編寫到發行就要一年呢,學開發一定要學最新的技術哦。
2.很多時候跟著書和不系統的視頻學習,會發現沒有目標,學了很多卻不知道自己到底能夠做出什麽成績。要有一個清晰的職業學習規劃哦,畢竟你不是興趣愛好學著玩,是想要加入BAT等一線企業作職業開發工程師呢。
學習過程中會遇到很多問題,這時候去群裏問不一定有人回答你,百度也不知道百度什麽。本來可以2小時搞好的學習項目,結果搞了10個小時,慢慢會有挫敗感。一定要堅持下去!!!
這裏推薦一下我的前端學習交流扣qun:767273102,裏面都是學習前端的從最基礎的HTML+CSS+JS【炫酷特效,遊戲,插件封裝,設計模式】到移動端HTML5的項目實戰的學習資料都有整理,送給每一位前端小夥伴。最新技術,與企業需求同步。好友都在裏面學習交流,每天都會有大牛定時講解前端技術!
0.1+0.2=?在前端裏,告訴你:≠0.3 !