js保留小数四舍五入问题(内含解决方法)

1.起因

今天业务突然发现10.155这个数字四舍五入保留两位小数有问题,结果是10.15,没有四舍五入。当时用的是toFixed(2)方法,查了一个文档发现js精度计算有问题导致的。

2.解决问题

后来在网上查了一些资料,找到了一个简单的方法

Math.round(value * 100) / 100
复制代码

但是这样还是不行,发现10.155还是会变成10.15,我一度怀疑是Math.round方法的问题,试了一些数,都没问题,然后试了一下10.155*100,结果竟然是1015.4999999999999,Math.round方法没问题,是计算的问题。然后又在网上找别的解决方案,基本都有一些小问题,然后决定自己写一个方法。

3.代码

try {
  const result = toDecimal(".995");
  console.log(result); //1.00
} catch (error) {
  console.log(error);
}

// 保留任意位小数
function toDecimal(number, precision = 2) {
  const temp = number;
  number = Number(number);
  // 判断是否为数字,不是数字抛出异常
  if (Number.isNaN(number)) {
    console.log("无效的数字:" + temp);
    throw new Error("无效的数字:" + temp);
  }

  number = String(number);
  let numbers = number.split(".");
  // 如果不是小数,补充对应的0
  if (numbers.length === 1) {
    return number + "." + "0".repeat(precision)
  } else {
    // 如果是小数 但位数比要保留的位数少 也是要补0
    if (numbers[1].length < precision) {
      return number + "0".repeat(precision - numbers[1].length);
    } else {
      // 取整数部分
      let intNumber = parseInt(number.split(".")[0]);
      // 取小数部分
      let decimal = number.split(".")[1];
      // 取出要保留的小数
      let frontDecimal = parseInt(decimal.substr(0, precision));
      // 去除要保留小数的后一位 
      const lastDecimal = parseInt(decimal.substr(precision, 1));
      // 如果最后以为大于5 就进位
      if (lastDecimal >= 5) {
        frontDecimal += 1;
      }
      //判断小数部位是否需要进位 类似于19.996 保留2位小数 就是20.00
      if (frontDecimal === Math.pow(10, precision)) {
        frontDecimal = "0".repeat(precision)
        intNumber += 1;
      }
      //处理 0.015 0.009 保留的小数中有0出现的情况
      frontDecimal = "0".repeat(precision - String(frontDecimal).length) + frontDecimal;

      return `${intNumber}.${frontDecimal}`
    }
  }
}
复制代码

你可能感兴趣的:(js保留小数四舍五入问题(内含解决方法))