面试题:JavaScript 中为什么会有 BigInt 的提案?

JavaScript 中引入 BigInt 的提案,主要是为了解决Number 类型在表示和操作大整数时的精度限制问题

核心原因:Number 类型的精度限制

在 JavaScript 中,所有的数字(包括整数和浮点数)都使用 IEEE 754 双精度 64 位浮点数格式存储。这种格式虽然能表示很大的数值范围,但整数的安全范围是有限的

1. Number.MAX_SAFE_INTEGER

  • JavaScript 能精确表示的最大整数2^53 - 1,即 9,007,199,254,740,991
  • 超过这个值的整数,精度会丢失
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1); // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2); // 9007199254740992 ← 和上面一样!精度丢失

2. 实际问题场景

在以下场景中,需要处理超过 Number.MAX_SAFE_INTEGER 的整数:

  • 金融计算:处理高精度金额、大额交易、加密货币(如比特币的 satoshi 单位)。
  • 数据库主键:许多数据库(如 MySQL 的 BIGINT)使用 64 位整数作为主键,其范围远超 Number.MAX_SAFE_INTEGER
  • 科学计算:处理大数运算、密码学算法(如 RSA)。
  • 时间戳:某些系统使用纳秒级时间戳,可能超出安全整数范围。
  • 唯一标识符:如 Twitter 的 Snowflake ID、分布式系统的唯一 ID。
// 一个常见的问题:数据库 ID 被错误地“四舍五入”
const userId = 9007199254740993; // 数据库中的真实 ID
const jsonStr = JSON.stringify({ id: userId });
// JSON.stringify 会将其转换为字符串?不,它会尝试保留为数字,但精度已丢失
const parsed = JSON.parse(jsonStr);
console.log(parsed.id); // 9007199254740992 ← 错误的 ID!可能导致安全或数据问题

BigInt 的解决方案

BigInt 是一种新的原始数据类型(primitive type),用于表示任意精度的整数

如何使用

  • 在整数字面量后加 n123n
  • 使用 BigInt() 构造函数:BigInt("123")
const bigInt1 = 9007199254740993n;
const bigInt2 = BigInt("9007199254740993");

console.log(bigInt1 === bigInt2); // true
console.log(bigInt1 + 1n); // 9007199254740994n ← 精确计算

BigInt 的特点

  • 可以表示任意大的整数(只受内存限制)。
  • Number 不兼容:不能直接与 Number 进行混合运算。
  • 不能使用 Math 对象中的方法。
  • 不能转换为 Number(使用 Number(bigInt) 会抛出错误)。
  • JSON.stringify 中不被原生支持(需要自定义 toJSON 方法)。
// 错误:混合运算
// 1 + 1n; // TypeError

// 正确:类型一致
1n + 1n; // 2n

总结

问题回答
为什么有 BigInt 提案?因为 Number 类型无法安全表示超过 2^53 - 1 的整数,导致精度丢失。现代应用(如金融、数据库、加密)需要处理大整数,因此需要 BigInt 来提供任意精度的整数支持

BigInt 的引入,使 JavaScript 能够更安全、精确地处理大整数运算,填补了语言在数值处理上的关键空白。

THE END
喜欢就支持一下吧
点赞7 分享