解决前端运算精度的问题
解决前端运算精度的问题
一、H5处理方式
1.前端在运算过程中:计算机二进制计算时会存在精度问题
/*解决运算精度问题*/ numberAdd: function(num1, num2) { //两数相加 num1 = !num1 ? 0 : num1; num2 = !num2 ? 0 : num2; return common.operationNumber(num1, num2, '+'); }, numberSub: function(num1, num2) { //两数相减 num1 = !num1 ? 0 : num1; num2 = !num2 ? 0 : num2; return common.operationNumber(num1, num2, '-'); }, numberMul: function(num1, num2) { //两数相乘 num1 = !num1 ? 0 : num1; num2 = !num2 ? 0 : num2; return common.operationNumber(num1, num2, '*'); }, numberDiv: function(num1, num2) { //两数相除 num1 = !num1 ? 0 : num1; num2 = !num2 ? 0 : num2; return common.operationNumber(num1, num2, '/'); }, operationNumber: function(arg1, arg2, operator) { var oper = ['+', '-', '*', '/']; // 不合法的运算 if (isNaN(arg1) || isNaN(arg2) || oper.indexOf(operator) < 0) { return NaN; } // 除以0 if (operator === '/' && Number(arg2) === 0) { return Infinity; } // 和0相乘 if (operator === '*' && Number(arg2) === 0) { return 0; } // 相等两个数字相减 if ((arg1 === arg2 || Number(arg1) === Number(arg2)) && operator === '-') { return 0; } var r1, r2, max, _r1, _r2; try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 } try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 } max = Math.max(r1, r2) _r1 = max - r1; _r2 = max - r2; if (_r1 !== 0) { arg1 = arg1 + '0'.repeat(_r1) } if (_r2 !== 0) { arg2 = arg2 + '0'.repeat(_r2) } arg1 = Number(arg1.toString().replace('.', '')) arg2 = Number(arg2.toString().replace('.', '')) var r3 = operator === '*' ? (max * 2) : (operator === '/' ? 0 : max); var newNum = eval(arg1 + operator + arg2); if (r3 !== 0) { var nStr = newNum.toString(); nStr = nStr.replace(/^-/, ''); if (nStr.length < r3 + 1) { nStr = '0'.repeat(r3 + 1 - nStr.length) + nStr; } nStr = nStr.replace(new RegExp('(\\\d{' + r3 + '})$'), '.$1'); if (newNum < 0) { nStr = '-' + nStr; } newNum = nStr * 1; } return newNum; },
二、小程序处理方式
1.小程序语法与h5有点区别
// 运算精度 const resolveFloat = { //除法 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) {} r1 = Number(arg1.toString().replace('.', '')) r2 = Number(arg2.toString().replace('.', '')) return resolveFloat.accMul(r1 / r2, Math.pow(10, t2 - t1)) }, //乘法 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) ) }, //加法 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 }, //减法 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 ((arg1 * m - arg2 * m) / m).toFixed(n) } }