JavaScript的Number类型因IEEE 754限制无法精确表示多数小数,所谓“精确度控制”实为规避精度陷阱:小数运算宜转整数再还原(如元→分),用Math.round防舍入误差;浮点比较须用容差(Math.abs(a-b)<ε)而非===。

JavaScript 的 Number 类型基于 IEEE 754 双精度浮点数,天生无法精确表示大多数十进制小数(如 0.1、0.2),整数也仅在 ±9007199254740991 范围内安全。所谓“精确度控制”,本质不是提升精度,而是规避精度陷阱——用合适策略绕过浮点表示缺陷。
小数运算:转整数再还原
适用于金额、百分比等常见场景,核心是避免小数参与中间计算。
- 把单位放大(如元 → 分、米 → 毫米),全程用整数加减乘除;
- 注意
Math.round(value * 100)比直接乘更稳妥,防止0.29 * 100得到28.999999999999996; - 最后统一除以放大倍数并保留所需位数,例如:
Number((centsTotal / 100).toFixed(2)); - 若结果可能超
Number.MAX_SAFE_INTEGER(如大额分值),需配合BigInt处理。
浮点比较:用容差代替相等判断
永远不要写 a === b 来比较两个浮点运算结果。
- 使用固定阈值:
Math.abs(a - b) ; - 更健壮的做法是动态容差:
Math.abs(a - b) ; - 对金融类比对,建议先转为整数再比较(如都转成分),避免浮点误差干扰逻辑。
高精度需求:交给专业库或类型
当业务本身要求无损十进制运算(如会计系统、科学计算),不应依赖原生 Number。
立即学习“Java免费学习笔记(深入)”;
-
decimal.js:功能完整,支持任意精度、四舍五入模式、指数运算,适合复杂金融场景; -
big.js:轻量、API 简洁,专注加减乘除和格式化,适合多数前端货币计算; -
BigInt:仅用于整数,必须用n后缀或BigInt()构造,不能与Number混用; - 后端传来的长 ID 或 BigDecimal 字段,必须作为字符串传输,前端不解析为
Number,再交由上述库处理。
显示与格式化:只在最终环节做
toFixed() 和 toPrecision() 是展示手段,不是计算手段。
-
(0.1 + 0.2).toFixed(2)返回"0.30",可用于 UI 显示,但不能拿这个字符串继续参与运算; - 若需数字类型结果,应
parseFloat("0.30"),但要注意这又回到了浮点数——所以更适合在展示层直接插值; - 避免链式调用
.toFixed().toFixed()或在循环中反复格式化,会累积不可控偏差。


















