数字计算小数点精度

export const toNewFixed = (num, digit = 2) => {
  const multiplePow = Math.pow(10, digit); // 多乘一位防止相乘后有小数点导致精度丢失,如:17.865
  return Math.round((num * (multiplePow * 10)) / 10) / multiplePow;
  // return Math.round(+num + 'e' + digit) / multiplePow
};

export const toFixedNum = (num, len = 2, str = "--") => {
  if ((num || num === 0) && !isNaN(num)) {
    return toNewFixed(num, len).toFixed(len); // toFixed 四舍五入有问题 用只于补0,如25.615.toFixed(2)='25.61'
  }
  return num || str;
};

// 相乘
export function multiplicationFn(mulArr = [], decimal, showType = 'number') {
  let decLen = 0; // 相乘数的小数点总长度
  let tNum = 1; // 相乘后的总数
  mulArr.forEach(ele => {
    const valArr = (ele || 0).toString().split('.');
    decLen += valArr[1] ? valArr[1].length : 0;
    tNum = tNum * valArr.join(''); // 转换成整数
  })
  const multiplePow = Math.pow(10, decLen)
  tNum = tNum / multiplePow
  if (decimal || decimal === 0) {
    return showType === 'string' ? toFixedNum(tNum, decimal) : toNewFixed(tNum, decimal)
  }
  return Number(tNum)
}

// 多个数值相除
export function beDividedFn(divideArr = [], decimal, showType = 'number') {
    if (divideArr.some(e => !e)) {
        return ''; // 除数或被除数为0或无值时返回空
    }

    let sNum = divideArr.splice(0, 1)[0] || 0; // 被除数,初始值为数组的第一个值
    const divisorNum = divideArr.length > 1 ? multiplicationFn(divideArr) : divideArr[0]; // 除数

    const nDivideArr = [sNum, divisorNum]

    const decimalArr = nDivideArr.map(n => {
    const valArr = (n || 0).toString().split('.');
    return valArr[1] ? valArr[1].length : 0;
  })
  // 获取最大的小数点长度
  const maxDecimal = Math.max.apply(null, decimalArr);
  const subPow = Math.pow(10, maxDecimal);

    sNum = Math.round(sNum * subPow);
    sNum = sNum / Math.round(divisorNum * subPow);

    if (decimal || decimal === 0) {
    return showType === 'string' ? toFixedNum(sNum, decimal) : toNewFixed(sNum, decimal)
  }

  return Number(sNum)
}

// 相加
export function accumulationFn(addArr = [], decimal) {
  let tNum = 0; // 相加后的总数
  if (!addArr.length) {
    return tNum;
  }
  const decimalArr = addArr.map(n => {
    const valArr = (n || 0).toString().split('.');
    return valArr[1] ? valArr[1].length : 0;
  })
  // 获取最大的小数点长度
  const maxDecimal = Math.max.apply(null, decimalArr);
  const addPow = Math.pow(10, maxDecimal);
  addArr.forEach(ele => {
    tNum += Math.round((ele || 0) * addPow);
  })
  tNum = tNum / addPow;
  if (decimal || decimal === 0) {
    return toFixedNum(tNum, decimal) // 不与后台交互,仅作页面显示用,如小计数据
  }
  return Number(tNum)
}


// 相减
export function subtractFn(subArr = [], decimal) {
  const decimalArr = subArr.map(n => {
    const valArr = (n || 0).toString().split('.');
    return valArr[1] ? valArr[1].length : 0;
  })
  // 获取最大的小数点长度
  const maxDecimal = Math.max.apply(null, decimalArr);
  const subPow = Math.pow(10, maxDecimal);

  let sNum = subArr.splice(0, 1)[0] || 0; // 相减的数,初始值为数组的第一个值

  sNum = Math.round(sNum * subPow);

  subArr.forEach(ele => {
    sNum -= Math.round((ele || 0) * subPow);
  })

  sNum = sNum / subPow;
  if (decimal || decimal === 0) {
    return toFixedNum(sNum, decimal)
  }
  return Number(sNum)
}

 

posted @ 2023-01-04 15:32  日升月恒  阅读(56)  评论(0)    收藏  举报