lcgrand.c
上传用户:aozhi88
上传日期:2022-07-10
资源大小:255k
文件大小:3k
源码类别:

行业应用

开发平台:

Visual C++

  1. /* Prime modulus multiplicative linear congruential generator
  2.    Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and Roberts'
  3.    portable FORTRAN random-number generator UNIRAN.  Multiple (100) streams are
  4.    supported, with seeds spaced 100,000 apart.  Throughout, input argument
  5.    "stream" must be an int giving the desired stream number.  The header file
  6.    lcgrand.h must be included in the calling program (#include "lcgrand.h")
  7.    before using these functions.
  8.    Usage: (Three functions)
  9.    1. To obtain the next U(0,1) random number from stream "stream," execute
  10.           u = lcgrand(stream);
  11.       where lcgrand is a float function.  The float variable u will contain the
  12.       next random number.
  13.    2. To set the seed for stream "stream" to a desired value zset, execute
  14.           lcgrandst(zset, stream);
  15.       where lcgrandst is a void function and zset must be a long set to the
  16.       desired seed, a number between 1 and 2147483646 (inclusive).  Default
  17.       seeds for all 100 streams are given in the code.
  18.    3. To get the current (most recently used) integer in the sequence being
  19.       generated for stream "stream" into the long variable zget, execute
  20.           zget = lcgrandgt(stream);
  21.       where lcgrandgt is a long function. */
  22. /* Define the constants. */
  23. #define MODLUS 2147483647
  24. #define MULT1       24112
  25. #define MULT2       26143
  26. /* Set the default seeds for all 100 streams. */
  27. static long zrng[] =
  28. {         1,
  29.  1973272912, 281629770,  20006270,1280689831,2096730329,1933576050,
  30.   913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
  31.   824064364, 150493284, 242708531,  75253171,1964472944,1202299975,
  32.   233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
  33.   762430696,1922803170,1385516923,  76271663, 413682397, 726466604,
  34.   336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
  35.    68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
  36.  1774806513,2132545692,2079249579,  78130110, 852776735,1187867272,
  37.  1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
  38.   243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
  39.   498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
  40.   536444882,1663153658, 855503735,  67784357,1432404475, 619691088,
  41.   119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
  42.  1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
  43.  1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
  44.   190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
  45.   364849192,2049576050, 638580085, 547070247 };
  46. /* Generate the next random number. */
  47. float lcgrand(int stream)
  48. {
  49.     long zi, lowprd, hi31;
  50.     zi     = zrng[stream];
  51.     lowprd = (zi & 65535) * MULT1;
  52.     hi31   = (zi >> 16) * MULT1 + (lowprd >> 16);
  53.     zi     = ((lowprd & 65535) - MODLUS) +
  54.              ((hi31 & 32767) << 16) + (hi31 >> 15);
  55.     if (zi < 0) zi += MODLUS;
  56.     lowprd = (zi & 65535) * MULT2;
  57.     hi31   = (zi >> 16) * MULT2 + (lowprd >> 16);
  58.     zi     = ((lowprd & 65535) - MODLUS) +
  59.              ((hi31 & 32767) << 16) + (hi31 >> 15);
  60.     if (zi < 0) zi += MODLUS;
  61.     zrng[stream] = zi;
  62.     return (zi >> 7 | 1) / 16777216.0;
  63. }
  64. void lcgrandst (long zset, int stream) /* Set the current zrng for stream
  65.                                           "stream" to zset. */
  66. {
  67.     zrng[stream] = zset;
  68. }
  69. long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */
  70. {
  71.     return zrng[stream];
  72. }