rng.c

来自「Simulation Modeling,Discrete Event Simul」· C语言 代码 · 共 121 行

C
121
字号
/* -------------------------------------------------------------------------  * This is an ANSI C library for random number generation.  The use of this  * library is recommended as a replacement for the ANSI C rand() and srand() * functions, particularly in simulation applications where the statistical * 'goodness' of the random number generator is important. * * The generator used in this library is a so-called 'Lehmer random number * generator' which returns a pseudo-random number uniformly distributed * between 0.0 and 1.0.  The period is (m - 1) where m = 2,147,483,647 and * the smallest and largest possible values are (1 / m) and 1 - (1 / m) * respectively.  For more details see: *  *       "Random Number Generators: Good Ones Are Hard To Find" *                   Steve Park and Keith Miller *              Communications of the ACM, October 1988 * * Note that as of 7-11-90 the multiplier used in this library has changed * from the previous "minimal standard" 16807 to a new value of 48271.  To * use this library in its old (16807) form change the constants MULTIPLIER * and CHECK as indicated in the comments. * * Name              : rng.c  (Random Number Generation - Single Stream) * Authors           : Steve Park & Dave Geyer * Language          : ANSI C * Latest Revision   : 09-11-98 * -------------------------------------------------------------------------  */#include <stdio.h>#include <time.h>#include "rng.h"#define MODULUS    2147483647L /* DON'T CHANGE THIS VALUE                   */#define MULTIPLIER 48271L      /* use 16807 for the "minimal standard"      */#define CHECK      399268537L  /* use 1043616065 for the "minimal standard" */#define DEFAULT    123456789L  /* initial seed, use 0 < DEFAULT < MODULUS   */static long seed = DEFAULT;    /* seed is the state of the generator        */   double Random(void)/* --------------------------------------------------------------------- * Random is a Lehmer generator that returns a pseudo-random real number * uniformly distributed between 0.0 and 1.0.  The period is (m - 1) * where m = 2,147,483,647 amd the smallest and largest possible values * are (1 / m) and 1 - (1 / m) respectively.                              * ---------------------------------------------------------------------    */{  const long Q = MODULUS / MULTIPLIER;  const long R = MODULUS % MULTIPLIER;        long t;  t = MULTIPLIER * (seed % Q) - R * (seed / Q);  if (t > 0)     seed = t;  else     seed = t + MODULUS;  return ((double) seed / MODULUS);}   void PutSeed(long x)/* ------------------------------------------------------------------- * Use this (optional) procedure to initialize or reset the state of * the random number generator according to the following conventions: *    if x > 0 then x is the initial seed (unless too large) *    if x < 0 then the initial seed is obtained from the system clock *    if x = 0 then the initial seed is to be supplied interactively * -------------------------------------------------------------------- */{  char ok = 0;  if (x > 0L)    x = x % MODULUS;                          /* correct if x is too large  */  if (x < 0L)                                     x = ((unsigned long) time((time_t *) NULL)) % MODULUS;                if (x == 0L)                                    while (!ok) {      printf("\nEnter a positive integer seed (9 digits or less) >> ");      scanf("%ld", &x);      ok = (0L < x) && (x < MODULUS);      if (!ok)        printf("\nInput out of range ... try again\n");    }  seed = x;}   void GetSeed(long *x)/* -------------------------------------------------------------------- * Use this (optional) procedure to get the current state of the random * number generator.                     * -------------------------------------------------------------------- */{  *x = seed;}   void TestRandom(void)/* ------------------------------------------------------------------- * Use this (optional) procedure to test for a correct implementation. * -------------------------------------------------------------------     */{  long   i;  long   x;  double u;  PutSeed(1);                                /* set initial state to 1 */  for(i = 0; i < 10000; i++)    u = Random();  GetSeed(&x);                               /* get the new state      */  if (x == CHECK)     printf("\n The implementation of Random is correct\n");  else    printf("\n\a ERROR - the implementation of Random is not correct\n");}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?