首頁  >  文章  >  web前端  >  探討javascript浮點數值運算是捨入誤差的原因

探討javascript浮點數值運算是捨入誤差的原因

巴扎黑
巴扎黑原創
2017-07-22 16:54:281627瀏覽

問題

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

產生原因

於是趕快翻書來拯救自己的靈魂以及肉體,發現書中赫然寫著:ECMAScrip是基於IEEE754數值浮點計算,這種數值計算方法會將數值儲存為二進位然後進行計算,由於浮點數用二進位表達時是無窮的,所以在進行算術計算時會產生舍入誤差,由於舍入誤差的存在,浮點數計算的精確度遠不如整數計算,最後記住了永遠不要測試某個特定浮點數的數值

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

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


以上轉載附上原始網址


 

#toFixed() 方法應該也可以傻瓜式地處理一部分舍入誤差問題。

語法:number.toFixed(x)       x:規定小數的位數,是 0 ~ 20 之間的值,包括 0 和 20,有些實作可以支援更大的數值範圍。如果省略了該參數,將會以 0 取代。

 


END


 

#

以上是探討javascript浮點數值運算是捨入誤差的原因的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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