前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库JavaScript 安全整数范围
JavaScript值与类型

JS 的 Number 能精确表示的整数范围是多少?超过了会怎样?

Number 基于 IEEE 754 双精度浮点,有效精度是 53 位二进制。安全整数范围是 -(2^53 - 1) 到 2^53 - 1,也就是正负 9007199254740991。超过这个范围,相邻的整数会被舍入成同一个值,运算结果就不对了。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#值与类型
先看核心答案读代码示例
理解线索

双精度浮点的整数边界

  1. 53 位有效精度52 位尾数加 1 位隐含位,总共能精确表示 53 位二进制整数
  2. 安全整数从负的 2^53-1 到正的 2^53-1,每个整数都能唯一表示
  3. 舍入行为超出后按最接近偶数规则舍入,相邻整数可能合并

Number.MAX_SAFE_INTEGER 和 Number.MAX_VALUE 差了几百个数量级,前者是精确整数的边界,后者是浮点数的最大值。

核心回答

先记住这个答案

JavaScript 的 Number 类型遵循 IEEE 754 双精度浮点标准,有效精度是 53 位二进制。所以安全整数的范围是从 -(2^53 - 1) 到 2^53 - 1,对应 Number.MIN_SAFE_INTEGER 和 Number.MAX_SAFE_INTEGER,也就是正负 9007199254740991。超过这个范围,并不是所有整数都能精确表示了——相邻整数可能被舍入成同一个值,导致加法、比较等运算出错。需要精确大整数时,应该用 BigInt。

  • 最大安全整数是 2^53 - 1
  • 超出后相邻整数可能相等
  • BigInt 提供任意精度整数
  • 用 Number.isSafeInteger 检查整数

为什么边界是 2 的 53 次方减 1

双精度浮点由 1 位符号、11 位指数和 52 位尾数组成。规格化的浮点数在尾数前面隐含了一个 1,所以实际有效位数是 53 位。53 位能表示的最大整数就是 2^53 - 1,也就是 9007199254740991。

当数值增长到 2^53 时,需要 54 位才能精确表示每一个整数,但尾数只有 53 位,所以步长变成了 2——引擎只能表示偶数。2^53 本身能表示(因为它正好是 2 的幂),但 2^53 + 1 就无法表示了,会被舍入成 2^53。

MAX_SAFE_INTEGER 溢出示例JavaScript
console.log(Number.MAX_SAFE_INTEGER);
var a = Number.MAX_SAFE_INTEGER + 1;
var b = Number.MAX_SAFE_INTEGER + 2;
console.log(a);
console.log(b);
console.log(a === b);
console.log(Number.isSafeInteger(a));
查看输出与解释
9007199254740991
9007199254740992
9007199254740992
true
false

a 和 b 本该差 1,但 +2 的结果被舍入成了和 +1 一样的值。Number.isSafeInteger() 返回 false,说明这个数已经不在安全范围内了。

实际项目里什么时候会踩到这个坑

最常见的场景是后端返回的 ID 超过了安全整数范围。比如雪花算法生成的订单号是 64 位长整型,很多已经超过 9007199254740991。前端用 JSON.parse 解析响应时,JavaScript 会把 JSON 里的数字字面量直接存成 Number,这时候精度就丢了。两个不同的订单号可能变成同一个数字,用户点开的可能不是自己那个订单。

解决办法是让后端把大 ID 序列化成字符串,前端全程当字符串处理。如果确实需要做数值运算,就用 BigInt。BigInt 可以表示任意大小的整数,不存在精度丢失的问题。

用 BigInt 做精确大整数运算JavaScript
var big = BigInt('9007199254740993');
console.log(big + 1n);
console.log(typeof big);
查看输出与解释
9007199254740994
bigint

BigInt 通过在数字后面加 n 或用 BigInt() 构造,运算时也要用 BigInt 字面量(1n),不能和普通 Number 直接混用。big + 1 会抛 TypeError,必须写成 big + 1n。

回答前,多想一步

容易答错的地方

以为超过 MAX_SAFE_INTEGER 就完全无法表示
超出安全范围的数仍然存在,Number.MAX_VALUE 大约是 1.8e308,远大于 MAX_SAFE_INTEGER。只是整数的步长变大了,不是每个整数都能唯一表示。打个比方,安全范围内你能精确到每一厘米,超出后只能精确到每两厘米甚至更粗。
混淆 MAX_VALUE 和 MAX_SAFE_INTEGER
Number.MAX_VALUE 是最大的有限浮点数,约 1.8e308。Number.MAX_SAFE_INTEGER 是 2^53 - 1,约 9e15。两者差了几百个数量级。面试中把它们搞混会暴露概念不清晰。
试着用自己的话回答

面试官还会怎么问?

为什么安全边界是 2^53 - 1 而不是 2^53?

2^53 本身可以精确表示,但 2^53 + 1 无法表示,会被舍入成 2^53。安全整数要求这个数和它相邻的整数都能精确表示,2^53 的下一个整数 2^53 + 1 已经丢了,所以 2^53 不算安全整数,边界取到 2^53 - 1。

BigInt 和 Number 混合运算会怎样?

直接做加减乘除会抛 TypeError,因为它们是不同的原始类型。但关系比较是允许的:1n < 2 返回 true,1n === 1 返回 false(类型不同),1n == 1 返回 true(宽松相等做了转换)。

怎么快速判断一个数是不是安全整数?

用 Number.isSafeInteger(),它内部的逻辑等价于:先检查是不是整数(Number.isInteger()),再检查绝对值是否小于等于 Number.MAX_SAFE_INTEGER。传入非 number 类型直接返回 false。

从一道题,走向一组知识

把知识连起来

值与类型

字符串是原始类型,为什么还能调用 toUpperCase 这样的方法?

(42).toString(2) 能看到数字的二进制表示,包装对象让原始值也能调用方法。

值与类型

typeof 和 instanceof 分别在什么场景下用?各有什么坑?

typeof 42n 返回 "bigint",和 typeof 42 返回的 "number" 不同,两者是独立的原始类型。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • Number.MAX_SAFE_INTEGER

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 为什么边界是 2 的 53 次方减 1
  3. 实际项目里什么时候会踩到这个坑
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑