JS浮点数舍入误差无法修复,需用整数运算规避:加减法统一放大取整再还原,乘除法按小数位缩放,自定义四舍五入函数替代toFixed,用EPSILON做误差容差比较。

JS 数值计算中的舍入误差不能“修复”,但可以通过算法规避或控制——核心思路是避免直接操作浮点数,转而用整数运算模拟,再按需还原小数位。
用字符串转整数放大法做四则运算
将小数转为整数(去掉小数点),完成运算后再除以对应倍数。该方法不依赖 Math.round 或 toFixed,从源头避开二进制表示缺陷。
-
加减法:找出两数中小数位数最大值
n,统一乘以10ⁿ变成整数相加/减,再除以10ⁿ -
乘法:分别统计两数小数位数
a和b,先去小数点相乘,再除以10^(a+b) -
除法:同样先转整数,再用整数除法配合补零或高精度缩放(如乘以
10^k再取整)模拟小数除法
自定义四舍五入函数(绕过 toFixed 的修约陷阱)
toFixed 实际采用“四舍六入五成双”规则,且底层仍是浮点数,易出错(如 1.005.toFixed(2) === "1.00")。可手动实现标准四舍五入:
- 对数字
num保留d位小数:先放大10ᵈ倍 → 加0.5→ 向下取整 → 再缩小10ᵈ倍 - 关键代码:
Math.floor(num * Math.pow(10, d) + 0.5) / Math.pow(10, d) - 注意处理负数:需用
Math.sign分离符号,或改用Math.round配合偏移(更稳妥)
用 Number.EPSILON 控制误差容差比较
不用于“修正”结果,而是让判断更鲁棒。例如 0.1 + 0.2 === 0.3 返回 false,但可用误差范围判定是否“足够接近”:
- 写成
Math.abs((0.1 + 0.2) - 0.3) - 适用于条件判断、断言、金融系统中的等值校验等场景
- 注意:EPSILON 是
2⁻⁵² ≈ 2.22e-16,仅适合小数值;大数需按比例缩放容差
超大数或高精度场景直接换库
当涉及货币、科学计算或超过 Number.MAX_SAFE_INTEGER(9007199254740991) 的整数时,整数放大法也会溢出。此时应引入专业库:
-
decimal.js:轻量、API 简洁,支持任意精度十进制运算 -
big.js:比bignumber.js更小,专为财务计算优化 - 用法示例:
new Decimal('0.1').plus('0.2').toString()→'0.3',无误差


















