UNIX 时间戳溢出 · 2038 年问题
2147483647
2³¹ − 1  ·  INT32_MAX  ·  第八个梅森素数
0000
:
00
:
00
:
00
距离 2038-01-19 03:14:07 UTC 溢出归零
epoch 0 · 1970-01-01 --.----% overflow · 2038-01-19
▼   向下了解这个数字
// 关于 2147483647
01
它是 32 位有符号整数的边界
计算机用二进制存储数字。一个 32 位有符号整数,最高位是符号位(0 为正,1 为负),剩余 31 位用来表示数值大小。31 个 1 组成的二进制数,换算成十进制正是 2³¹ − 1 = 2147483647。
0111 1111 1111 1111 1111 1111 1111 1111
= 2³¹ − 1
= 2,147,483,647
= 0x7FFFFFFF
如果再加 1,符号位翻转,数值变成 −2147483648——溢出,程序崩溃,历史上无数 bug 由此而生。

02
2038 年问题:Unix 时钟即将归零
Unix 系统以 1970 年 1 月 1 日 00:00:00 UTC(称为"epoch")为起点,用一个 32 位有符号整数记录流逝的秒数。这个计数器将在 2038-01-19 03:14:07 UTC 走到 2147483647——然后溢出,跳回 1901 年。

这被称为 Y2K38 问题,与 20 世纪末的千年虫危机性质相同:都是数字表示范围不足。解决方案是将时间戳升级为 64 位整数,届时下一次溢出将发生在距今约 2920 亿年后。

03
它同时是一个梅森素数
形如 2ⁿ − 1 的素数被称为梅森素数,以 17 世纪法国数学家马兰·梅森命名。2147483647 是第八个梅森素数(n = 31),也是已知的四个双梅森素数之一——即 2^(2ⁿ−1) − 1 也是素数。

1772 年,莱昂哈德·欧拉证明了它的素性,并在写给丹尼尔·伯努利的信中报告了这一结论。它此后整整 95 年保持"人类已知最大素数"的头衔,直到 1867 年才被超越。

04
它在现实世界留下的印记
这个数字从数学课本走进了现实,悄悄潜伏在各种系统里:
MySQL  INT  列的最大值  ·  2147483647
Java  Integer.MAX_VALUE  ·  2147483647
Excel 单个工作表最大行数上限(历史版本)
PlayStation 3 某游戏存档金币数上限  ·  2147483647
Minecraft 早期版本地图坐标边界  ·  "Far Lands"
无数程序员曾被这个数字坑过:用 int 存电话号码、存用户 ID、存访问量……然后某天数字突然溢出,变成负数,或者直接归零。