js在計算浮點數時可能不夠準確,會產生舍入偏差的問題,這是使用基於IEEE745數值的浮點計算的通病,並不是ECMAScript一家,其餘使用相同數值格式的語言也存在這個問題。
這裏講一下js浮點數加、減、乘、除的正確作法。javascript
整數的乘法運算是準確的,這裏咱們將浮點數的乘法運算轉化爲整數乘法,而後除以10的他們小數位數之和次方,如0.03
乘以0.05
,轉化爲3 * 5 / 1e4
java
//乘法運算 0.03 * 0.05 變成3 * 5 / 10^4 function mul(a, b) { var n = 0; var c = a.toString(10); var d = b.toString(10); try { n += c.split('.')[1].length; } catch (f) {} try { n += d.split('.')[1].length; } catch (f) {} return (+c.replace('.', '')) * (+d.replace('.', '')) / Math.pow(10, n); }
這裏咱們將浮點數分別乘以小數位最大的以後,再相加,而後除以10的小數位數最大的次方,如0.03
加上0.5
,轉化爲3 + 50 / 1e2
測試
//加法運算 function add(a, b) { var c, d, n; try { c = (a + '').split('.')[1].length; } catch(f) { c = 0; } try { d = (b + '').split('.')[1].length; } catch(f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (a * e + b * e)/ e; }
同加法,如0.03
減去0.5
,轉化爲3 - 50 / 1e2
code
//除法運算 function sub(a, b) { var c, d, n; try { c = (a + '').split('.')[1].length; } catch(f) { c = 0; } try { d = (b + '').split('.')[1].length; } catch(f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (a * e - b * e) / e; }
也相似加法,將兩個數各自乘以10的他們小數位最大的次方,再相除,而後乘以1e(除數小數位 - 被除數小數位)
如0.03
除以0.5
,轉化爲3 / 50
再乘以1e-1
blog
//除法運算 function dev(a, b) { var c, d, e, f; try { c = (a + '').split('.')[1].length; } catch (f) { c = 0; } try { d = (b + '').split('.')[1].length; } catch (f) { d = 0; } return e = (a + '').replace('.', '') , f = (b + '').replace('.', ''), mul(e / f, Math.pow(10, d - c)); }
測試代碼:ip
console.log(sub(0.03, 0.5));//-0.2 console.log(add(0.03, 0.5));//0.53 console.log(mul(0.03, 0.5));//0.015 console.log(dev(0.03, 0.5));//0.06
輸出結果 :
it