在javascript中整數和浮點數都屬於Number數據類型(簡單數據類型中的一種),咱們常常會發如今打印1.0
這樣的浮點數的結果是1
而非1.0
,這是因爲保存浮點數的內存空間是保存整數值的兩倍,因此ECMAScript會不失時機地將浮點數轉換爲整數。
上面這種狀況雖然讓強迫症患者有點不舒服,可是好歹也不是什麼大錯,接下來這種狀況就很嚇人了。例如咱們在計算0.1
加0.2
時,它的輸出結果不是0.3
,而是0.3000000000000004
。what the fuck?!第一次遇到這種狀況的童鞋有沒有感受到世界觀受到了挑戰?javascript
因而趕快翻書來拯救本身的靈魂以及肉體,發現書中赫然寫着:ECMAScrip是基於IEEE754數值浮點計算若是不知道IEEE754是什麼就點我吧,這種數值計算方法會將數值保存爲二進制而後進行計算,因爲浮點數用二進制表達時是無窮的,因此在進行算術計算時會產生舍入偏差,因爲舍入偏差的存在,浮點數計算的精確度遠遠不如整數計算,最後記住了永遠不要測試某個特定浮點數的數值。
因此楊絳先生說的對,年輕人就是想的多讀書少,沒文化老是動不動就會懷疑人生,因此仍是要多讀書啊!!!java
所謂對症下藥,知道了問題產生的緣由那麼就能夠找到問題的解決方案啦。既然是因爲浮點數的二進制爲無窮數產生的偏差,這種偏差在整數運算中不會存在,聰明的你是否是窺破真相了呢?沒錯,那就是在運算工程中將浮點數轉換爲整數,再將得出的結果轉換爲浮點數。客官,下面是新鮮上的代碼~測試
//加法 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轉換爲整數進行計算,而後再轉換回浮點數 }
done,科科~url