数据丢失精度处理

206 阅读1分钟
# 获取小数位数
function getDecimalLength(arg = '') {
  try {
    return arg.toString().split(".")[1].length
  } catch (e) {
    return 0
  }
}

# 转换数字
function getNum(arg = '') {
  return Number(arg.toString().replace(".", ""))
}

function changeNum(arg1 = '', arg2 = '', isAdd = true) {
  function changeInteger(arg, r, maxR) {
    if (r != maxR) {
      let addZero = ''
      for (let i = 0; i < maxR - r; i++) {
        addZero += '0'
      }
      arg = Number(arg.toString().replace('.', '') + addZero)
    } else {
      arg = getNum(arg)
    }
    return arg
  }
  let r1, r2, maxR, m;
  r1 = getDecimalLength(arg1)
  r2 = getDecimalLength(arg2)
  maxR = Math.max(r1, r2)
  arg1 = changeInteger(arg1, r1, maxR)
  arg2 = changeInteger(arg2, r2, maxR)
  m = Math.pow(10, maxR)
  if (isAdd) {
    return (arg1 + arg2) / m
  } else {
    return (arg1 - arg2) / m
  }
}

/**
 * 加法运算,避免数据相加小数点后产生多位数和计算精度损失
 * @param num1 加数1
 * @param num2 加数2
 */
function numAdd(num1, num2) {
  return changeNum(num1, num2)
}

/**
 * 减法运算,避免数据相减小数点后产生多位数和计算精度损失
 * @param num1 被减数
 * @param num2 减数
 */
export function numSub(num1, num2) {
  return changeNum(num1, num2, false)
}

/**
 * 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失
 * @param arg1 被乘数
 * @param arg2 乘数
 */
function numMulti(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)
}

/**
 * 除法运算,避免数据相除小数点后产生多位数和计算精度损失
 * @param arg1 被除数
 * @param arg2 除数
 */
function numDiv(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 numMulti((r1 / r2), Math.pow(100, t2 - t1))
}