前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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值与类型

Number 能表示的最小正数是多少?为什么会有 +0 和 -0?

最小正数是 Number.MIN_VALUE,约等于 5e-324,也就是 2 的 -1074 次方,比它还小的正数会下溢成 0。正负零的存在是因为浮点数有独立的符号位,数值为 0 时符号位照样可以是 1。

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

数轴两端的三个特殊值

  1. Number.MIN_VALUE最接近 0 的正数,约 5e-324,属于非规格化数
  2. 下溢结果比最小正数还小时被舍入成 0,符号保留
  3. 负零符号位为 1、其余全 0,数值上等于 0

Number.MIN_VALUE 容易和 Number.MIN_SAFE_INTEGER 搞混。后者是 -9007199254740991,是最小的安全整数;真正「最小的数」是 -Infinity,最小的有限数是 -Number.MAX_VALUE。

核心回答

先记住这个答案

Number 能表示的最小正数是 Number.MIN_VALUE,约等于 5e-324,精确值是 2 的 -1074 次方。运算结果如果比它的一半还小,就会下溢成 0。之所以有 +0 和 -0,是因为 IEEE 754 双精度浮点数用一个单独的比特存符号,数值部分全是 0 时,符号位是 0 就是 +0,是 1 就是 -0。两者用 === 比较相等,只有 Object.is 或 1 / x 这类运算能区分出来。

  • MIN_VALUE 是最小正数
  • 比最小正数还小会下溢成 0,负数下溢成 -0
  • Object.is 能区分正零和负零
  • 1 / -0 得到负无穷大

最小正数和下溢

双精度浮点数有 11 位指数、52 位尾数。正常情况下尾数前面隐含一个 1,这种叫规格化数,最小是 2 的 -1022 次方,约 2.2e-308。为了让数值更平滑地逼近 0,标准还定义了非规格化数,去掉隐含的 1,最小可以到 2 的 -1074 次方,这就是 Number.MIN_VALUE。

用代码看最小正数和下溢JavaScript
console.log(Number.MIN_VALUE)          // 最小正数
console.log(Number.MIN_VALUE === 2 ** -1074)
console.log(Number.MIN_VALUE / 2)      // 再小一半就下溢成 0
console.log(2 ** -1022)                // 最小的「规格化」正数
console.log(Number.MIN_SAFE_INTEGER)   // 最小安全整数,是个负数
// 负数下溢,结果是负零
const tiny = -Number.MIN_VALUE / 2
console.log(tiny === 0, Object.is(tiny, -0))
查看输出与解释
5e-324
true
0
2.2250738585072014e-308
-9007199254740991
true true

Number.MIN_VALUE / 2 正好落在 0 和最小正数的正中间,按「就近舍入,平局取偶」的规则被舍成了 0,这就是下溢。下溢不会报错,也不会给出 NaN,只是悄悄变成 0。 最后两行是负零的来源之一:一个极小的负数下溢时,数值没了,但符号还在。这正是负零存在的意义,它保留了「这个结果是从负方向逼近 0 的」这个信息。

负零怎么产生、怎么识别

负零在日常代码里不常见,但一些普通运算会悄悄产生它:负数乘以 0、Math.round(-0.4)、负数下溢、-0 字面量。它和 0 的区别只在少数几个地方露出来。

=== 分不出来,除法和 Object.is 能JavaScript
const nz = -0
console.log(nz === 0)              // === 认为相等
console.log(Object.is(nz, 0))      // Object.is 能区分
console.log(1 / nz, 1 / 0)         // 除法把符号暴露出来
console.log(String(nz), JSON.stringify(nz)) // 转字符串时符号丢了
// 这些运算会悄悄产生 -0
console.log(Object.is(Math.round(-0.4), -0))
console.log(Object.is(0 * -5, -0))
console.log(Math.atan2(0, -0), Math.atan2(0, 0))
查看输出与解释
true
false
-Infinity Infinity
0 0
true
true
3.141592653589793 0

=== 和 == 都把 +0 和 -0 当成相等,includes、Set、Map 用的 SameValueZero 也一样。只有 Object.is 用的 SameValue 会区分。在没有 Object.is 的年代,判断 -0 的写法是 x === 0 && 1 / x === -Infinity。 String(-0) 和 JSON.stringify(-0) 都得到 '0',所以把 -0 渲染到页面上是看不出来的。反过来 toLocaleString 在部分环境下会输出 '-0',展示层遇到过就知道原因了。

负零在业务里什么时候有用
符号本身有时是信息。比如一个表示速度或方向的值,从 -0.3 逐渐衰减到 0,保留负号就知道物体最后是朝反方向运动的。Math.atan2(0, -0) 得到 π 而不是 0,也是靠负零区分了方向。大多数业务代码不需要关心它,但在做数值格式化、动画插值或者写对比工具函数时要考虑进去。
回答前,多想一步

容易答错的地方

把 Number.MIN_VALUE 当成最小的数
它是最接近 0 的正数,不是最小值。比它小的数多的是,比如 0、所有负数、-Infinity。要表示「最小的有限数」应该用 -Number.MAX_VALUE,写循环找最小值时初始值用 Infinity,别用 Number.MIN_VALUE。
以为下溢会报错或变成 NaN
JavaScript 的数值运算基本不抛异常。上溢变成 Infinity,下溢变成 0,只有 0 / 0、Infinity - Infinity 这类没有意义的运算才得到 NaN。
以为 Object.is 和 === 只差在 NaN
它们有两处不同:Object.is(NaN, NaN) 是 true,Object.is(0, -0) 是 false。只记住第一处,就解释不了为什么 React 的状态比较会把 0 和 -0 当成不同的值。
试着用自己的话回答

面试官还会怎么问?

Number.EPSILON 和 Number.MIN_VALUE 有什么区别?

Number.EPSILON 约 2.22e-16,是 1 和比 1 大的下一个浮点数之间的距离,用来描述 1 附近的精度,常用于浮点比较的容差。Number.MIN_VALUE 是整个数轴上离 0 最近的正数,描述的是能表示的最小量级,两者差了几百个数量级。

数组的 includes 和 indexOf 对 -0 和 NaN 怎么处理?

includes 用 SameValueZero,把 +0 和 -0 视为相等,也能找到 NaN。indexOf 用严格相等,同样把 +0 和 -0 视为相等,但找不到 NaN,[NaN].indexOf(NaN) 是 -1。

怎么把一个可能是 -0 的值规范成 0?

加 0 就行,-0 + 0 的结果是 +0。也可以写 x || 0,因为 -0 是假值,不过这个写法会把其它假值也变成 0,要确认输入一定是数字。

从一道题,走向一组知识

把知识连起来

值与类型

数字分隔符 _ 能用在哪些字面量里?写在哪些位置会报错?

数字分隔符能让 2 ** -1074 这种极值常量的十进制写法更好读,但不改变可表示范围。

值与类型

对象转字符串时,先调 valueOf 还是先调 toString?

String(-0) 得到 '0',负号在转字符串时丢了,和对象转字符串一样都是隐式转换的细节。

参考资料

  • JavaScript:值与类型参考资料

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

本题目录
  1. 先记住这个答案
  2. 最小正数和下溢
  3. 负零怎么产生、怎么识别
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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