浮点数精度丢失无法完全避免,但可通过整数运算、toFixed+parseFloat舍入、Decimal.js等库、误差范围比较等方法缓解;关键是否定直接等值比较与累计计算。

浮点数精度丢失无法完全避免,因为这是二进制表示小数的固有限制(如 0.1 在二进制中是无限循环小数),但可以通过合适的方法绕过或缓解问题,关键在于不直接依赖浮点数做等值比较、累计计算或金融类精确运算。
用整数代替浮点数做精确计算
对金额、比例、计数等有固定小数位的场景,把单位放大(如元 → 分、米 → 毫米),全程用整数运算,最后再转回显示形式。
- 错误写法:
let total = 0.1 + 0.2; console.log(total === 0.3); // false - 推荐写法:
const totalCents = 10 + 20; // 30 分 → 0.3 元;显示时除以 100 - 适用场景:电商价格、财务统计、游戏金币、传感器采样计数等
使用 toFixed + parseFloat 做简单舍入(仅限展示或非关键逻辑)
toFixed(n) 返回字符串,能控制小数位数,配合 parseFloat 可用于临时修正显示误差,但不解决底层精度问题,不能用于条件判断或累计计算。
- 示例:
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 // true - 注意:
toFixed是四舍五入,且在某些浏览器对负数处理不一致,慎用于金融核心逻辑 - 只建议用于 UI 展示、日志打印、调试输出等非计算路径
引入 Decimal.js 或 big.js 等高精度库
当必须进行多步浮点运算(如科学计算、利率复利、坐标变换)且结果需严格可控时,用专为十进制设计的库替代原生 Number。
- Decimal.js 支持任意精度、四则运算、比较、幂运算,API 类似原生数字:
new Decimal('0.1').plus('0.2').equals('0.3') // true - big.js 更轻量,适合前端嵌入;mathjs 则适合复杂数学表达式
- 务必传字符串初始化(
new Decimal(0.1)仍会先丢失精度),即用'0.1'而非0.1
避免浮点数等值比较,改用误差范围判断
判断两个浮点数是否“相等”,应检查它们的差值是否小于一个极小阈值(epsilon),而不是用 ===。
- 常见 epsilon 值:
Number.EPSILON(约 2.22e-16),适用于一般情况;对业务数据可设更宽松值如1e-6或1e-10 - 写法示例:
Math.abs(a - b) - 特别注意:涉及大数时,epsilon 应随数值量级缩放(相对误差),可用
Math.abs(a - b)
不复杂但容易忽略。核心就三条:该用整数的时候别用小数,该用字符串初始化的时候别传数字,该比大小的时候别用全等。

















