首頁  >  文章  >  web前端  >  javascript浮點數值運算bug

javascript浮點數值運算bug

高洛峰
高洛峰原創
2016-10-20 17:53:581375瀏覽

問題

在javascript中整數和浮點數都屬於Number資料型態(簡單資料型別中的一種),我們常發現在印出1.0這樣的浮點數的結果是1而非1.0,這是由於保存浮點數的記憶體空間是儲存整數值的兩倍,所以ECMAScript會不失時機地將浮點數轉換為整數。 
上面這種狀況雖然讓強迫症患者有點不舒服,但是好歹也不是什麼大錯,接下來這種情況就很嚇人了。例如我們在計算0.1加0.2時,它的輸出結果不是0.3,而是0.3000000000000004。 what the fuck? !第一次遇到這種狀況的童鞋有沒有感覺到世界觀受到了挑戰?

產生原因

於是趕快翻書來拯救自己的靈魂以及肉體,發現書中赫然寫著:ECMAScrip是基於IEEE754數值浮點計算如果不知道IEEE754是什麼就點我吧,這種數值計算方法會將數值儲存為二進位然後進行計算,由於浮點數用二進位表達時是無窮的,所以在進行算術計算時會產生捨入誤差,由於捨入誤差的存在,浮點數計算的精確度遠不如整數計算,最後記住了永遠不要測試某個特定浮點數的數值。
所以楊綛先生說的對,年輕人就是想的多讀書少,沒文化總是動不動就會懷疑人生,所以還是要多讀書啊! ! !

解決方案

所謂對症下藥,知道了問題產生的原因那麼就可以找到問題的解決方案啦。既然是因為浮點數的二元為無窮數所產生的誤差,這種誤差在整數運算中不會存在,那麼聰明的你是不是窺破真相了呢?沒錯,那就是在運算工程中將浮點數轉換為整數,再將得出的結果轉換為浮點數。客官,以下是新鮮上的代碼~

//加法  
function FloatAdd(arg1,arg2){  
       var r1,r2,m; 
       try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0; //参数1为整数};  //参数1小数点后的位数
       try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0; //参数2为整数}; //参数2小数点后的位数
       m=Math.pow(10,Math.max(r1,r2));  //取其中较大的位数
       return (arg1*m+arg2*m)/m;   //先将arg1和arg2转换为整数进行计算,然后再转换回浮点数
  }


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn