js toFixed()四舍五入问题

本文探讨了JavaScript中toFixed方法在处理特定数值时的四舍五入问题,提供了两种改进方案来确保结果符合预期。

在js中使用tofix进行四舍五入的时候,发现对16.175使用toFixed(2)得到的是16.17,并不是16.18

let num = 16.175
console.log(num.toFixed(2))//输出结果是16.17

解决办法1

function newFixed(num, len) {
  if(Object.is(parseFloat(num), NaN)) {
    return console.log("非数字");
  }
  num = parseFloat(num);
  return (Math.round((num + Number.EPSILON) * Math.pow(10, len)) / Math.pow(10, len)).toFixed(len);
}
let num = newFixed(16.175,2)
console.log(num );//16.18

方法2

 newFixed(number, n) {
     if (n > 20 || n < 0) {
          throw new RangeError('toFixed() digits argument must be between 0 and 20');
      }

      if (isNaN(number) || number >= Math.pow(10, 21)) {
          return number.toString();
      }

      if (typeof (n) == 'undefined' || n == 0) {
          return (Math.round(number)).toString();
      }
      let result = number.toString();
      const arr = result.split('.');
      // 整数的情况
      if (arr.length < 2) {
          result += '.';
          for (let i = 0; i < n; i += 1) {
              result += '0';
          }
          return result;
      }
      const integer = arr[0];
      const decimal = arr[1];
      if (decimal.length == n) {
          return result;
      }

      if (decimal.length < n) {
          for (let i = 0; i < n - decimal.length; i += 1) {
              result += '0';
          }
          return result;
      }
      result = integer + '.' + decimal.substr(0, n);
      const last = decimal.substr(n, 1);
      // 四舍五入,转换为整数再处理,避免浮点数精度的损失
      if (parseInt(last, 10) >= 5) {
          const x = Math.pow(10, n);
          result = (Math.round((parseFloat(result) * x)) + 1) / x;
          result = result.toFixed(n);
      }
      return result;
  },
### JavaScript 中 `toFixed` 的四舍五入问题及其解决方案 #### 问题描述 JavaScript 中的 `toFixed(n)` 方法用于将数字转换为指定小数位数的字符串表示形式。然而,该方法采用的是 **银行家舍入法** 而非传统的四舍五入规则[^1]。这种舍入方式可能导致某些情况下结果不符合预期。 以下是银行家舍入法的核心规则: - 如果舍弃部分小于 5,则向下取整; - 如果舍弃部分大于等于 6,则向上取整; - 如果舍弃部分正好是 5,则依据前一位是否为偶数决定:如果是偶数则舍去;如果为奇数则进一[^3]。 由于这一特性,在实际开发中可能会遇到一些意外情况,比如: ```javascript const test = 36.665; console.log(test.toFixed(2)); // 输出 "36.66",而非预期中的 "36.67" ``` 此现象表明默认行为可能无法完全满足传统意义上的四舍五入需求。 --- #### 解决方案概述 为了实现更精确的传统四舍五入效果,可以采取以下几种替代策略或自定义函数来弥补原生 `toFixed()` 方法存在的不足之处。 --- ### 方案一:基于 `Math.round()` 实现简单修正逻辑 通过手动调整数值后再调用 `Math.round()` 来完成真正的四舍五入操作。这种方法适用于大多数场景下的快速修复。 代码如下所示: ```javascript function myFixed(num, digit) { num = parseFloat(num); return (Math.round((num + Number.EPSILON) * Math.pow(10, digit)) / Math.pow(10, digit)).toFixed(digit); } // 测试案例 console.log(myFixed(36.665, 2)); // 正确输出:"36.67"[^2] ``` 这里的关键在于利用 `(Number.EPSILON)` 增强浮点运算稳定性并配合幂次方放大缩小技巧达到目标精度范围内的理想结果。 --- ### 方案二:重写完整的 `toFixed` 函数 对于更加复杂或者严格控制的要求来说,可以直接编写一个全新的定制化版本代替原有的内置功能。下面提供了一个较为通用的例子供参考: ```javascript export function customToFixed(x, n) { let f_x = parseFloat(x); if (isNaN(f_x)) { console.warn('传递参数不是数字!'); return false; } f_x = Math.round(x * Math.pow(10, n)) / Math.pow(10, n); let s_x = f_x.toString(); let pos_decimal = s_x.indexOf('.'); if (pos_decimal < 0) { pos_decimal = s_x.length; s_x += '.'; } while (s_x.length <= pos_decimal + n) { s_x += '0'; } return s_x; } // 测试案例 console.log(customToFixed(36.665, 2)); // 正确输出:"36.67"[^4] ``` 这段脚本不仅实现了标准意义下的四舍五入算法,还额外增加了错误检测机制以及确保最终返回值始终具备固定长度的小数格式。 --- ### 总结与建议 尽管 JavaScript 提供了便捷实用的工具如 `toFixed()` ,但在涉及高精度过滤时仍需谨慎对待其潜在缺陷。针对不同业务环境可以选择适当的方式加以改进优化——无论是简单的辅助计算还是全面覆盖型的新建模块皆可行之有效。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值