mt19937 prng如何准确地用于python随机模块函数?

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

I ran this with Python 3.8.2 (not that it should matter too much). This is not what I would expect from a MT19937 32 bit PRNG. To be exact, I was expecting values similar to the ones presented in this website: https://create.stephan-brumme.com/mersenne-twister/

Python与其他语言有何不同?有没有办法我自己复制Python生成的位? (此外,如何从32位字长的整数生成random()从0到1的浮点数?)

谢谢!

评论
  • 淡夏之
    淡夏之 回复

    Python的播种算法与链接使用的算法完全不同。 Twister具有庞大的状态,只有32位的种子只能将其置于相对较小数量的可能状态。 Python的种子算法使用任意大的参数。

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

    Python's code to generate an IEEE double is the same as the genrand_res53() function in the Twister's original C code:

    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。