JavaScript浮点数精度丢失源于IEEE 754二进制表示限制,非bug;解决关键是避免直接使用原生浮点数,推荐转整数运算、toFixed+parseFloat组合或decimal.js等高精度库。

JavaScript 中浮点数运算的精度丢失源于 IEEE 754 双精度浮点数表示法的固有限制,比如 0.1 + 0.2 === 0.30000000000000004。这不是 bug,而是二进制无法精确表示某些十进制小数导致的。解决的关键是**避免直接用原生浮点数做关键精度计算**,尤其在金融、计费、统计等场景。
转成整数再运算(最常用、最可靠)
把小数乘以 10 的幂次变成整数,计算完成后再除回去。适用于已知小数位数的场景(如金额通常保留两位)。
- 例如处理元为单位的金额:
(0.1 * 100 + 0.2 * 100) / 100 === 0.3 - 封装成工具函数更安全,需注意四舍五入和边界(如
parseFloat((num).toFixed(10))防止科学计数法干扰) - 注意:不能简单用
Math.round,要先放大再取整再还原,否则仍可能出错
使用 toFixed + parseFloat 组合(适合展示层)
toFixed 返回字符串,能按指定小数位四舍五入;再用 parseFloat 转回数字(避免字符串参与后续计算时隐式转换出错)。
- 示例:
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 - ⚠️ 注意:
toFixed是对「当前值」四舍五入,不是防止计算过程误差,仅适合最终结果修正 - 不推荐用于中间计算,多次调用会累积舍入误差
引入高精度计算库(适合复杂业务)
当涉及多位小数、混合运算或需要严格遵循会计规则时,用成熟库更稳妥。
立即学习“Java免费学习笔记(深入)”;
- decimal.js:功能全面,支持任意精度、四舍五入模式、科学计数法,API 类似原生 Number
- big.js:轻量(~6KB),专注基本四则运算,适合前端嵌入
- bignumber.js:较老但稳定,社区支持广
- 用法示例:
new Decimal('0.1').plus('0.2').equals('0.3')—— 字符串输入是关键,避免初始化就失真
避免常见误区
有些“技巧”看似简洁,实则不可靠。
- ❌ 不要用
Math.round(num * 100) / 100直接修结果:若num本身已是误差值(如0.1+0.2),放大后四舍五入仍可能不准 - ❌ 不要依赖
Number.EPSILON做相等判断来“掩盖”问题:它只适用于比较,不能修复计算逻辑 - ❌ 不要把所有数字都 toString 再 parse:没解决根本问题,还增加开销
- ✅ 正确思路:从源头控制——输入用字符串或整数,运算过程用整数或专用类型,输出再格式化


















