原因
Java和JavaScript中計算小數運算時,都會先將十進制的小數換算到對應的二進制,一部分小數並不能完整的換算為二進制,這里就出現了第一次的誤差。待小數都換算為二進制后,再進行二進制間的運算,得到二進制結果。然后再將二進制結果換算為十進制,這里通常會出現第二次的誤差。
解決辦法
加法
function accAdd(arg1,arg2){ var r1,r2,m; try{ r1 = arg1.toString().split(".")[1].length; }catch(e){r1=0} try{ r2 = arg2.toString().split(".")[1].length; }catch(e){r2=0} m = Math.pow(10,Math.max(r1,r2)); return (arg1*m+arg2*m)/m; } Number.prototype.add = function (arg){ return accAdd(arg, this); } console.log(0.7.add(0.87));
除法
function accDiv(arg1,arg2){ var t1=0,t2=0,r1,r2; try{ t1=arg1.toString().split(".")[1].length; }catch(e){} try{ t2=arg2.toString().split(".")[1].length; }catch(e){} with(Math){ r1=Number(arg1.toString().replace(".","")); r2=Number(arg2.toString().replace(".","")); return (r1/r2)*pow(10,t2-t1); } } Number.prototype.div = function (arg){ return accDiv(this, arg); } console.log(11.5.div(0.5));
乘法
function accMul(arg1,arg2){ var m=0,s1=arg1.toString(), s2=arg2.toString(); try{ m+=s1.split(".")[1].length }catch(e){} try{ m+=s2.split(".")[1].length }catch(e){} return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) } Number.prototype.mul = function (arg){ return accMul(arg, this); } console.log(1.3.mul(0.4));
減法
function acCut(arg1, arg2){ var r1, r2, m; try{ r1 = arg1.toString().split('.')[1].length; }catch(e){} try{ r2 = arg2.toString().split('.')[1].length; }catch(e){} m = Math.pow(10, Math.max(r1, r2)); return (arg1*m - arg2*m)/m; } Number.prototype.cut = function(arg){ return acCut(this, arg); } console.log(1.543.cut(0.5642));