首页 > 解决方案 > mt19937 prng 究竟如何用于 python 随机模块函数?

问题描述

from random import *
seed(5489)
hex(getrandbits(32)) # '0xc9a0e034'
hex(getrandbits(32)) # '0x38feb21f'

我用 Python 3.8.2 运行它(不是说它应该太重要)。这不是我对 MT19937 32 位 PRNG 的期望。确切地说,我期待的值类似于本网站中提供的值:https ://create.stephan-brumme.com/mersenne-twister/

Python 与其他语言有何不同?有没有办法让我自己重现 Python 生成的位?(另外,从 0 到 1 的 random() 浮点数是如何从 32 位字大小的整数生成的?)

谢谢!

标签: pythonrandommt19937

解决方案


Python 的播种算法与链接使用的算法完全不同。Twister 有一个庞大的状态,一个只有 32 位的种子只能将它放入相对微不足道的可能状态中。Python 的种子算法使用任意大的参数。

要重现 Python 的播种算法,您必须阅读 C 代码并自己进行仿真。没有任何关于它的定义。

genrand_res53()Python 生成 IEEE double 的代码与 Twister 的原始 C 代码中的函数相同:

uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6;
return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));

实际上,一个 32 位 Twister 输出的前 27 位左移 26,“下一个”32 位 Twister 输出的前 26 位填充低 26 位,得到一个 53 位值除以2.0**53。


推荐阅读