数字精度丢失

1. JS 能表示的最大数字

JS 使用 IEEE 754 双精度浮点数(64 位)来表示数字,可安全表示的最大整数是 2^53 - 1,即 Number.MAX_SAFE_INTEGER。

补充:超过这个范围的整数会出现"精度丢失",即末尾的奇数会被取整到偶数。

Number.MAX_SAFE_INTEGER;  // 9007199254740991
Number.MIN_SAFE_INTEGER;  // -9007199254740991

console.log(9007199254740992 === 9007199254740993); // true,已经不安全

// 位运算、序列化大于 2^53 的整数 ID(如雪花 ID)都要用 BigInt 或字符串
const id = BigInt('1234567890123456789');

2. 浮点数精度问题

经典的 0.1 + 0.2 !== 0.3:

0.1 + 0.2;            // 0.30000000000000004
0.1 + 0.2 === 0.3;    // false

3. 如何解决精度问题

  • 业务允许的容差比较:判断两数之差是否小于 Number.EPSILON(约 2.22e-16)。
  • 整数化:把小数按固定精度(如分、厘)乘以 10^n 转成整数运算,最后再除回去。
  • 第三方库:decimal.js、bignumber.js、big.js,内部用字符串/数组表示精确十进制。
  • 金融/ID 场景:使用 BigInt 或服务端用字符串返回。
// 容差比较
function isEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}
isEqual(0.1 + 0.2, 0.3); // true

// 整数化(以"分"为单位做金额计算)
const price = (1999 + 99) / 100;     // 20.98
const priceStr = ((1999 + 99) / 100).toFixed(2); // "20.98"

来源整理自:vue3js.cn 面试官系列