# 随机数发生器原理

• 看起来是[0,1]之间的随机均匀分布
• 运行快，内存消耗低
• 可以重复，英文是reproducible：支持stream，即支持将一个随机数序列分割为相互无覆盖的子集，每个子集称为一个stream

• 随机数的取值只能是[0,m-1]中离散的整数值，为了让其除以m后看起来很连续，m需要取较大的值
• 一旦在第i个随机数和之前的某个随机数相同，那么后面的随机数将和之前的序列相同，出现周期性
• 全周期：希望[0,m-1]的每个值在一个周期内都出现一次，从而更有效地表现为均匀的[0,1)分布

• m和c互质
• 如果q是质数（只能被1和它本身整除）且能够整除m，则它能够整除a - 1
• 如果4整除m，4整除a-1

float lcgrand(int stream);
void  lcgrandst(long zset, int stream);
long  lcgrandgt(int stream);

#define MODLUS 2147483647
#define MULT1       24112
#define MULT2       26143

static long zrng[] =
{         1,
1973272912, 281629770,  20006270,1280689831,2096730329,1933576050,
913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
824064364, 150493284, 242708531,  75253171,1964472944,1202299975,
233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
762430696,1922803170,1385516923,  76271663, 413682397, 726466604,
336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
1774806513,2132545692,2079249579,  78130110, 852776735,1187867272,
1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
536444882,1663153658, 855503735,  67784357,1432404475, 619691088,
119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
364849192,2049576050, 638580085, 547070247 };

float lcgrand(int stream)
{
long zi, lowprd, hi31;

zi     = zrng[stream];
lowprd = (zi & 65535) * MULT1;
hi31   = (zi >> 16) * MULT1 + (lowprd >> 16);
zi     = ((lowprd & 65535) - MODLUS) +
((hi31 & 32767) << 16) + (hi31 >> 15);
if (zi < 0) zi += MODLUS;
lowprd = (zi & 65535) * MULT2;
hi31   = (zi >> 16) * MULT2 + (lowprd >> 16);
zi     = ((lowprd & 65535) - MODLUS) +
((hi31 & 32767) << 16) + (hi31 >> 15);
if (zi < 0) zi += MODLUS;
zrng[stream] = zi;
return (zi >> 7 | 1) / 16777216.0;
}

void lcgrandst (long zset, int stream)
{
zrng[stream] = zset;
}

long lcgrandgt (int stream)
{
return zrng[stream];
}

#include
#include "lcgrand.h"

int main(){
int i = 0;
for(i=0;i<10;i++)
{
printf("%f\n",lcgrand(0));
}
}

CC=gcc

MAKER_SRC=$(wildcard *.c) MAKER_OBJ=$(patsubst %.c,%.o,$(MAKER_SRC)) MAKER_EXE=test .PHONY:all all:$(MAKER_EXE)

$(MAKER_EXE):$(MAKER_OBJ)
$(CC) -o$@ $^ %.o:%.c$(CC) -c -o $@$<</div>

.PHONY:clean
• 本文已收录于以下专栏：

举报原因： 您举报文章：随机数发生器原理 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)