我试图用C语言创建Python中使用的mersennetwister(MT)。在
基于Lib/random.py以及读取the docs,整个机器翻译似乎是在{
The underlying implementation in C is both fast and threadsafe.
通过google搜索“Python随机”,我找到了this page on GitHub,它似乎正是我要找的,尽管它似乎不是官方的。在
我使用了源代码,除去了除了MT本身、seed函数和double creation函数之外的所有内容。我还更改了一些类型,使整数为32位。在
首先,这里是许可证信息(为了安全起见)
^{pr2}$这是一个精简的头文件(删除了Python的所有内容)。在
mt.h
:
#ifndef MT_H
#define MT_H
#include <stdint.h>
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
typedef struct {
uint32_t state[N];
uint32_t index;
} RandomObject;
static uint32_t
genrand_int32(RandomObject *self)
{
uint32_t y;
static uint32_t mag01[2]={0x0UL, MATRIX_A};
/* mag01[x] = x * MATRIX_A for x=0,1 */
uint32_t *mt;
mt = self->state;
if (self->index >= N) { /* generate N words at one time */
uint32_t kk;
for (kk=0;kk<N-M;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
}
for (;kk<N-1;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
self->index = 0;
}
y = mt[self->index++];
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}
static double
random_random(RandomObject *self)
{
uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
return (double)((a*67108864.0+b)*(1.0/9007199254740992.0));
}
static void
init_genrand(RandomObject *self, uint32_t s)
{
uint32_t mti;
uint32_t *mt;
mt = self->state;
mt[0]= s & 0xffffffffUL;
for (mti=1; mti<N; mti++) {
mt[mti] =
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
mt[mti] &= 0xffffffffUL;
/* for >32 bit machines */
}
self->index = mti;
return;
}
#endif
这里有一个主函数,它简单地创建一个MT对象,为它种子,然后抛出一个随机的double。在
main.c
#include <stdio.h>
#include "mt.h"
int main() {
RandomObject rand;
init_genrand(&rand, 0x1234);
printf("%lf\n", random_random(&rand));
return 0;
}
输出是:0.279194
。在
其思想是,当我在python中执行等效过程时,我会得到相同的随机数:
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> random.seed(0x1234)
>>> random.random()
0.9281175899596723
当然,输出是不同的(否则我不会在这里询问)。在
我的问题是:我的程序出了什么问题?我只是用错了来源吗?关于Python如何处理C返回的值,我是否做出了错误的假设?在
老实说,我对Python不太了解,所以我可能在某个地方犯了一个愚蠢的错误。在
您缺少的是,} instead (这是因为在Python中,一个整数可以是任意大小的,我们希望将种子的所有位捕获到该状态中)。在
random.seed()
没有调用init_genrand()
来设定初始状态but use ^{相关问题 更多 >
编程相关推荐