JavaScript数字类型为64位双精度浮点数,导致0.1+0.2≠0.3;整数安全范围为±(2^53−1);金额应转整数运算,浮点比较需用误差容忍。

JavaScript 的数字类型是 number,它统一用 64 位双精度浮点数(IEEE 754)表示整数和小数——这意味着它没有单独的 int 或 float 类型,也导致很多看似简单的计算会出人意料。
为什么 0.1 + 0.2 !== 0.3?
这是浮点数精度限制的直接体现:十进制小数 0.1 和 0.2 在二进制中是无限循环小数,存储时被截断,相加后误差累积,结果是 0.30000000000000004。
- 这不是 JavaScript 独有,所有遵循 IEEE 754 的语言(如 Python、Java)都存在
- 整数在
-(2^53 - 1)到2^53 - 1范围内可精确表示(即Number.MAX_SAFE_INTEGER) - 超过该范围的整数可能丢失精度,例如
9007199254740993 === 9007199254740992返回true
安全做数学计算的常用方式
取决于场景,没有“万能解”,但有明确取舍:
- 金额运算:一律转为整数(单位“分”),用
Math.round()配合乘除,避免小数参与中间计算 - 比较浮点数:不用
===,改用差值判断,例如Math.abs(a - b) - 大整数运算:超出
Number安全范围时,改用BigInt(注意:不能和number混用,否则报错TypeError: Cannot mix BigInt and other types) - 需要高精度小数(如科学计算):引入第三方库如
decimal.js或big.js,它们用字符串或数组模拟运算
parseInt、parseFloat 和一元加号 + 的区别
三者都能转字符串为数字,但行为差异明显,容易误用:
立即学习“Java免费学习笔记(深入)”;
-
parseInt("12.99")→12(只解析开头整数部分,遇到小数点就停) -
parseFloat("12.99px")→12.99(能解析小数,但同样在非数字字符处停止) -
+"12.99"→12.99(严格转换,任何非纯数字字符串都返回NaN,如+"12.99px") -
隐式转换(如
"12" * 1)也等价于一元加号,但可读性差,不建议用于关键逻辑
真正麻烦的不是“怎么算”,而是“什么时候该怀疑结果”。比如后端传来一个 ID 字符串 "90071992547409919",前端用 Number 解析后可能变成 90071992547409920——这种精度丢失不会报错,却会在业务层面引发数据错乱。











