JavaScript浮点数运算不精确是IEEE 754标准限制所致,非bug;解决方式包括转整数运算、toFixed+parseFloat组合、decimal.js等高精度库及EPSILON误差比较。

JavaScript 中浮点数运算不精确,本质是二进制无法精确表示多数十进制小数(如 0.1 + 0.2 !== 0.3),这不是 bug,而是 IEEE 754 双精度浮点数的标准限制。解决的关键不是“修复 JS”,而是根据场景选择合适的数据抽象方式。
转整数后运算(适合金额、计数等固定小数位)
将小数乘以 10n 转为整数计算,完后再除回去。这是最稳妥、无依赖的方案,尤其适用于货币(通常保留 2 位小数)。
- 例如:(0.1 * 100 + 0.2 * 100) / 100 === 0.3 → true
- 封装成工具函数更安全:避免多次乘除引入新误差,比如 parseFloat((num * 100).toFixed(0)) / 100
- 注意:toFixed() 返回字符串,需配合 parseFloat 或 Number 转回数值
使用 toFixed() + parseFloat 组合(简单场景快速修正显示)
toFixed(n) 会四舍五入并返回字符串,再用 parseFloat 转回数字,可解决显示层面的精度错乱(如 UI 展示、日志输出)。
- 例如:parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 → true
- 慎用于中间计算:因 toFixed 是舍入操作,连续多步运算可能累积舍入误差
- 推荐仅在最终展示前或单次校准值时使用
引入 decimal.js 或 big.js 等高精度库(需要严格精度的业务)
当涉及金融结算、科学计算或需保证全程无舍入误差时,应使用专为十进制设计的任意精度库。
立即学习“Java免费学习笔记(深入)”;
- decimal.js 功能全面,支持设置精度、舍入模式、指数范围,API 类似原生 Number
- 示例:new Decimal(0.1).add(0.2).equals(0.3) → true
- 注意:这些库返回的是对象而非原始 number,不能直接参与 === 比较或某些数学函数(如 Math.max),需调用 .toNumber() 或对应方法
避免直接比较浮点数相等(通用防御习惯)
不依赖 === 或 == 判断两个浮点结果是否“相等”,改用误差容忍(EPSILON)比较。
- 使用 Number.EPSILON:判断 Math.abs(a - b) < Number.EPSILON
- 对不同量级数值,建议用相对误差:Math.abs(a - b) <= Number.EPSILON * Math.max(Math.abs(a), Math.abs(b))
- 框架中常封装为 isClose(a, b, tolerance = 1e-10),提升可读性与复用性


















