javascript浮点数精度丢失是ieee 754标准导致的必然现象,非bug;解决需按场景选抽象方式:金额用整数运算、高精度用decimal.js、展示用tofixed+parsefloat、比较用容差判断。

JavaScript 中浮点数精度丢失不是 bug,而是 IEEE 754 双精度标准的必然表现——像 0.1、0.2 这类十进制小数在二进制中是无限循环小数,存储时被截断,导致计算结果偏差(如 0.1 + 0.2 === 0.30000000000000004)。解决的核心思路是:不强行“修 JS”,而是按业务场景选合适的数据抽象方式。
金额类固定小数位运算:用整数代替小数
适合价格、订单、计费等明确小数位数(如两位)的场景。全程避开浮点参与,零依赖、最稳妥。
- 统一单位放大:金额用“分”、利率用“万分之一”、百分比用“万分比”,例如
19.99 元 → 1999 分 - 放大时必须用
Math.round(num * factor),不能直接乘,防止放大过程就引入新误差 - 所有加减乘除都在整数间完成,最后再除以相同倍数还原,例如
(1999 + 200) / 100 → 21.99 - 注意安全上限:放大后不能超过
Number.MAX_SAFE_INTEGER(约9e15),否则整数本身也会失真
高精度全程计算:用 decimal.js 等库
适用于金融结算、科学计算、复利推演等要求全程无舍入误差的场景。它不依赖原生 Number,而是用字符串+十进制算法模拟精确运算。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 初始化必须传字符串,如
new Decimal('0.1').add('0.2');传0.1数字字面量会立刻失真 - 支持自定义精度、舍入模式(四舍五入/向上取整/银行家舍入)和指数范围
- 返回的是对象,不能直接
===比较或传给Math.max,要用.equals()或.toNumber() - 轻量推荐
decimal.js;复杂函数需求可选bignumber.js
仅用于展示或日志:toFixed + parseFloat 校准
这只修正最终输出,不改变计算逻辑,适合 UI 渲染、调试打印等非计算环节。
- 写法示例:
parseFloat((0.1 + 0.2).toFixed(10))→0.3 -
toFixed(n)返回字符串,必须转回数值才能继续参与计算 - 切勿在中间步骤反复使用:比如循环累加中每步都
toFixed,误差会逐次累积 - 注意
toFixed的四舍五入行为有例外(如1.335.toFixed(2)得'1.33'),对精度敏感场景慎用
浮点数比较:改用容差判断
这是高频出错点,永远不要用 === 判断两个浮点运算结果是否“相等”。
- 通用写法:
Math.abs(a - b) ,容差值根据业务精度要求调整(金额常用 <code>1e-2) - 封装成工具函数更安全:
function isEqual(a, b, epsilon = 1e-10) { return Math.abs(a - b) - 该方式不解决计算误差,但能避免因微小偏差导致的逻辑误判
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










