js 实现一个完美的toFixed(四舍五入)

1,156 阅读2分钟

toFixed问题

在JavaScript中,我们经常需要对数字进行精确的处理,比如保留小数位数。而toFixed()函数正是JavaScript提供的一种用于保留小数位数的方法。然而,由于浮点数在计算机中的存储方式,toFixed()四舍五入会在一些特殊情况下出现异常。如:

// 返回2.5
2.55.toFixed(1)

解决方案

常用解决方案

网络上大部分解决方案是通过自己重写保留小数位数的函数来解决问题,代码如下

function toFixed(num, digits = 0) {
  return (Math.round(num * Math.pow(10, digits)) / Math.pow(10, digits)).toFixed(digits)
}
// 返回1.25
toFixed(1.255, 2)

但是,这些方法仍然无法做到完美的保留小数位数,也会遇到一些出现‘.999的情况’

完美解决方案

完美的解决方案需要考虑以下几个问题:

  1. 解决科学计数法的问题
  2. 判断数字是否为负数
  3. 判断小数点位置
  4. 找到需要进行四舍五入的部分
  5. 核心处理逻辑
  6. 处理多余位数
  7. 处理负数的情况

通过以上步骤,我们可以得到完美的保留小数位数的函数,下边我们将展示下核心的代码逻辑,如果想要看完整代码,可以直接点击尾部了解

  // 核心处理逻辑
  if (parseInt(numArr[numArr.length - 1], 10) > 4) {
    // 如果最后一位大于4,则往前遍历+1
    for (let i = numArr.length - 2; i >= 0; i--) {
      numArr[i] = String(parseInt(numArr[i], 10) + 1);
      // 判断这位数字 +1 后会不会是 10
      if (numArr[i] === '10') {
        // 10的话处理一下变成 0,再次for循环,相当于给前面一个 +1
        numArr[i] = '0';
      } else {
        // 小于10的话,就打断循环,进位成功
        break;
      }
    }
  }
// 返回1.26
toFixed(1.255, 2)

在使用这个函数时,我们可以传入两个参数,第一个是需要保留小数位数的数字,第二个是需要保留的小数位数。如果第一个参数是整数或者小数位数不足,则直接调用toFixed()函数。如果第一个参数是科学计数法表示的数字,则先用toFixed()函数处理一下再进行保留小数位数的操作。

这个函数可以完美地解决toFixed()函数四舍五入的问题,同时也考虑了一些特殊情况的处理,如科学计数法的数字、负数等。如果你在实际开发中需要对数字进行精确的处理,可以使用这个函数,避免因toFixed()函数的问题而产生的错误。

附: 代码链接(自己写的工具函数库): github | npm 参考链接: link