物理芝士数学酱
26-07-23 22:14 微博认证:科学科普博主 微博原创视频博主

#今天要来点计算机科学吗?#

在计算机科学中是一个非常特殊的数字——16807

你可以在 PlayStation 5(FreeBSD 11)、几乎所有经典 Mac 游戏中找到它,甚至在 C++11 标准中也能看到!

给它一个合适的素数,你就能生成一个均匀分布的序列,覆盖超过 20 亿个值。

如今看来这似乎微不足道,但几十年来,随机数生成技术确实非常糟糕。这主要归咎于IBM。

两位研究人员帕克和米勒对糟糕的随机数生成器(RNG)深恶痛绝,于1988年向ACM发表了一篇题为

《随机数生成器:好的很难找》的论文。

他们并不是真的想开发一个完美的算法;更重要的是让它“足够好且高效”。

这被称为“最低标准”,是一个简短的乘法例程,仅有一行代码:

x = seed × 16807 mod 2^31 - 1

当然,这在32位硬件上运行得非常顺畅。只需几条指令就够了。

苹果将其纳入了CarbonLib,FreeBSD也采用了它,在随后的几十年里,它几乎无处不在。

几年后,人们发现48271的效果稍好一些。具体来说,在高达6维的谱测试中,它的分布更加均匀。

有趣的是,几乎没人听进去。FreeBSD直到2021年还在rand()中使用16807!

所以,如果你在反汇编代码中看到这个常量……嗯,现在你应该明白了 :)

(附注: 大多数 rand() 实现已转用其他线性同余生成器(LCG),或是梅森扭转算法等……但可以说 16807 至今仍相当普遍!)

发布于 黑龙江