javascript数字精度丢失的根本原因是number类型基于ieee 754双精度浮点标准,整数安全范围仅±(2⁵³−1),且十进制小数在二进制中无法精确表示,导致如0.1+0.2===0.30000000000000004等误差。

JavaScript 中数字精度丢失根本原因是 Number 类型基于 IEEE 754 双精度浮点数标准,整数安全范围仅限于 ±(253 − 1),且十进制小数(如 0.1、0.2)在二进制中无法精确表示,导致运算结果出现微小误差,比如 0.1 + 0.2 === 0.30000000000000004。
用字符串传大整数,避开解析阶段精度丢失
后端返回的 long 类型 ID、订单号等超安全整数范围的值(如 9223372036854775807),前端直接解析为 Number 会变成 9223372036854776000 —— 已失真。最稳妥做法是后端序列化为字符串,前端原样接收、展示或参与非计算类逻辑。
- Java 后端可用 Jackson 的
@JsonSerialize(using = ToStringSerializer.class)注解将 long 字段转字符串 - 前端无需 parseFloat 或 Number() 转换,直接用字符串做比较、拼接、渲染即可
- 若必须参与计算(如分页跳转),先确认是否真需数值运算;否则保持字符串更安全
金额/小数运算优先转整数再算
对货币、价格等固定小数位场景(如两位小数),把单位“分”代替“元”,全程用整数加减乘除,彻底绕过浮点误差。
- 例如:
0.1 + 0.2→ 拆为10 + 20 = 30(单位为“分”),再除以 100 得0.3 - 封装通用函数时,可自动提取最大小数位数:
const factor = Math.pow(10, Math.max(getDecimals(a), getDecimals(b))) - 注意:该法不适用于极大数(如超过
Number.MAX_SAFE_INTEGER),否则整数本身也会溢出
高精度计算用 decimal.js 或 bignumber.js
当业务需要可靠的小数运算(如金融计息、科学计算)或超大整数(如区块链地址、大额统计),引入专业库是最直接可靠的方案。
-
decimal.js默认十进制、支持设置精度和舍入模式,API 清晰:new Decimal('0.1').add('0.2').toString()→'0.3' -
bignumber.js更轻量,兼容性好,适合多数项目;支持链式调用和自定义精度 - 避免传入 Number 类型字面量(如
new Decimal(0.1)),应始终用字符串初始化,防止初始化阶段就失真
现代环境可用 BigInt 处理超大整数
对于纯整数且值远超 2^53−1 的场景(如哈希值、大质数、ID 运算),BigInt 是原生解决方案。
- 声明方式:
123n或BigInt("123");支持+、-、*、**等运算 - 注意:
BigInt不能与普通Number混合运算,会报错;比较需用===,不能用== - 兼容性需检查:Chrome 67+、Firefox 68+、Safari 14+ 支持;旧环境需 polyfill 或降级为字符串处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











