一、概述
有时间再来写......
二、使用
以下三种方法都可以解决前端的浮点型运算导致精度丢失的问题
1. toFixed()
toFixed()方法会采用四舍五入的方法保留指定位数的小数。
let a = 0.1 let b = 0.2 let c = a + b console.log(c) // 0.30000000000000004 c = parseFloat(0.1 + 0.2).toFixed(1) console.log(c) // 0.3
2. 将浮点数转换为整数运算
基本的思路就是通过将浮点数转换成整数进行计算,然后再将整数的小数点位调整,转回正确的浮点数结果。
// 加法函数 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; } // 取位数最大的 10^ n次方 m = Math.pow(10, Math.max(r1, r2)); return (arg1 * m + arg2 * m) / m; } //给Number类型增加一个add方法,使用时直接用 .add 即可完成计算。 Number.prototype.add = function (arg) { return accAdd(this, arg); }; //减法函数 function Subtr(arg1, arg2) { var 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 parseFloat(((arg1 * m - arg2 * m) / m).toFixed(n)); } Number.prototype.sub = function (arg) { return Subtr(this, arg); }; //乘法函数 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); }; //除法函数 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(0.1.add(0.2).add(0.3));//等价于0.1+0.2+0.3,输出0.6 console.log(0.1 + 0.2 + 0.3);//输出0.6000000000000001 console.log(0.6.sub(0.2).sub(0.3));//等价于0.6-0.2-0.3 输出0.1 console.log(0.6 - 0.2 - 0.3);//输出:0.09999999999999998 console.log(0.1.mul(0.2).mul(0.3)); //等价于0.1 * 0.2 * 0.3 输出0.006 console.log(0.1 * 0.2 * 0.3); //输出:0.006000000000000001 console.log(0.6.div(0.2).div(0.1)); //等价于0.6 / 0.2 / 0.1 输出30 console.log(0.6 / 0.2 / 0.1); //输出:29.999999999999993
3. 引入第三方库 decimal.js
既然有现成的,那就直接用,何必多此一举呢?推荐
let z = Decimal.add(0.1, 0.2)
console.log(z.toString())
参考: