解决前端运算精度的问题

解决前端运算精度的问题

一、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)
  }
}

 

posted @ 2022-04-25 10:05  时光独醒  阅读(5)  评论(0编辑  收藏  举报