日常开发中,常规计算快捷展示,一般针对金额计算。例如购物车、批量操作数据展示总金额等等,一般都是前端负责处理,并且性能交互效果好,但是会衍生一个很大的问题。小学水平的计算,js居然计算出这么大的问题,难道是读书不听课???这里涉及一个问题,js的计算精度。计算机的数据底层是0和1,二进制的,而我们常用是10进制。由于有一些浮点数用二进制表示时是无穷的,当浮点数转化为二进制进行存储时,会把超过53位之后的进行合并导致精读丢失。关键字眼,部分浮点数,那么我们将数据分为两类,存在浮点和不存在浮点,不存在的话直接换算,其他的有一位小数,我们直接*10,那不就是整数了!!!看!代码!!!
// 计算补充0数量 export const getZero = (a, b) => { let zero = '', len = 0; if (a > b) { len = a - b; } else { len = b - a; } for (let i = 0; i < len; i++) { zero += '0'; } return zero; }; // 浮点数转换整数 export const decimalToInteger = (a, b) => { let _a = a.toString(), _b = b.toString(); // 不存在小数 if (!_a.match(/\./g) && !_b.match(/\./g)) { return { _a, _b, multiple: 1 }; // 为浮点数 } else { const al = _a.match(/\./g) ? _a.split('.')[1] : '', bl = _b.match(/\./g) ? _b.split('.')[1] : '', max = Math.max(al.length, bl.length), // 核心一:将原数据扩大到原来的10的n(小数位数)次方。也就是整数的效果 multiple = Math.pow(10, max); _b = _b.replace(/\./g, ''); _a = _a.replace(/\./g, ''); if (al.length > bl.length) { _b += getZero(al.length, bl.length); } else { _a += getZero(al.length, bl.length); } return { _a, _b, multiple }; } }; // 加 export const add = (a, b) => { const { _a, _b, multiple } = decimalToInteger(a, b); // 核心二:将数据缩小回原效果。 return (Number(_a) + Number(_b)) / multiple; };
同理,其他四则运算:
// 减 export const subtract = (a, b) => { const { _a, _b, multiple } = decimalToInteger(a, b); return (Number(_a) - Number(_b)) / multiple; }; // 乘 export const multiply = (a, b) => { const { _a, _b, multiple } = decimalToInteger(a, b); return (Number(_a) * Number(_b)) / Math.pow(multiple, 2); }; // 除以 export const divide = (a, b) => { const { _a, _b, multiple } = decimalToInteger(a, b); return (Number(_a) / Number(_b)); };
不考虑内存大小和有更多计算要求的话,请使用更全面的math.js。
标签:const,金额,Number,js,return,length,export,multiple,异常 From: https://www.cnblogs.com/ljt-8961/p/16647483.html