在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中文網其他相關文章!