js为什么会出现数字精确度丢失
在JavaScript中,精度丢失通常是由于JavaScript数字类型的限制导致的。JavaScript使用IEEE 754双精度64位二进制格式来表示数字(即Number类型),这导致了两个主要的精度问题:
# 有限的精度范围
Number类型能表示的最小值和最大值是有限的。对于非常小或非常大的数值,可能会发生精度丢失。js 的 number 类型的最大值是 9007199254740992,这个值是 16 位。如果超过这个值,js 会出现不精确的现象。
console.log(9999999999999999 == 10000000000000000) // true
1
# 二进制浮点数表示
由于计算机使用二进制系统,而JavaScript的数字类型是基于二进制浮点数,所以十进制小数在转换为二进制浮点数时可能会有近似值。这意味着一些十进制小数无法精确地表示为二进制浮点数,从而导致精度丢失。
比如:0.1 + 0.2
十进制0.1 对应二进制0.000110011001100110011001100...
十进制0.2 转换为二进制同样是无限循环的:.00110011001100110011001100...
由于计算机不能存储无限循环的小数,它们使用最接近的有限位数的二进制小数来近似表示。当你对这些近似值进行计算时,误差会累积,导致最终结果与预期的精确值不符。
console.log(0.1 + 0.2) // 0.30000000000000004
1
只有x/2^n的数可以被精确表示,其它的小数都是近似数
提示
为什么在控制台直接console.log(0.2)会输出0.2而不是一个近似数呢?
虽然JavaScript使用IEEE 754标准来表示浮点数,它在内部存储浮点数的方式可能会导致一些精度问题,但在大多数情况下,JavaScript会尽量以最接近原始输入的方式显示浮点数。
# 解决方式
- 将小数转化成整数计算
- 借助js提供的静态值
Number.EPSILON判断是否相等,只要差值小于Number.EPSILON即可认定为相等。Math.abs(a-b) < Number.EPSILON - 使用三方库进行计算:
math.js、decimal.js
上次更新: 2025/09/05, 8:09:00