原因
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));