解决JavaScript计算不精确问题,现拿现用
1、说明
console.log( 1 - 0.8 ); //输出 0.19999999999999996 console.log( 6 * 0.7 ); //输出 4.199999999999999 console.log( 0.1 + 0.2 ); //输出 0.30000000000000004 console.log( 0.1 + 0.7 ); //输出 0.7999999999999999 console.log( 1.2 / 0.2 ); //输出 5.999999999999999 通过上面举出的例子可以看到,原生的js运算结果不一定准确,会丢失精度
2、网上解决方案(有bug 请勿使用)
// 加 function Add(arg1, arg2) { let 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; }; // 减 function Sub(arg1, arg2) { let r1, r2, m, n; 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)); n = r1 >= r2 ? r1 : r2; return ((arg1 * m - arg2 * m) / m).toFixed(2); } // 乘 function Mul(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) } // 除 function Div(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); } }
bug所在 console.log( Add(19.36, 601.19)); //输出 620.5500000000001
原因就是处理函数会将浮点数转化为整数来计算,但处理浮点数时采用的是没经过处理的乘法,所以最终得出错误结果。
3、修正方法
① 在最终返回结果的时候加上了toFixed,这是一种解决方法。
② 另外一种解决方法,既然是乘法出错,我们何不将乘法换成优化后的乘法。
所以我选择采用了第二种方法,对上面的错误代码进行优化
4、最终版(正确版)
// 精确运算 加 function add(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e; } // 精确运算 减 function sub(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e; } // 精确运算 乘 function mul(a, b) { var c = 0, d = a.toString(), e = b.toString(); try { c += d.split(".")[1].length; } catch (f) {} try { c += e.split(".")[1].length; } catch (f) {} return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c); } // 精确运算 除 function div(a, b) { var c, d, e = 0, f = 0; try { e = a.toString().split(".")[1].length; } catch (g) {} try { f = b.toString().split(".")[1].length; } catch (g) {} return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e)); }
最终测试 console.log( Add(19.36, 601.19)); //输出 620.55