mt19937 prng 如何准确地用于 python 随机模块功能?

How is mt19937 prng exactly used for python random module functions?

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 生成的位? (此外,运行dom() 是如何从 32 位字大小的整数生成从 0 到 1 的浮点数的?)

谢谢!

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

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

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

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,"the next" 32 位 Twister 输出的高 26 位填充低 26 位,得到 53 - 除以 2.0**53 的位值。