Random Number Gemerator
From
robin vowels@21:1/5 to
All on Sun Nov 12 09:48:21 2023
George Marsaglia wrote a number of RNGs, either by himself, or with others. Here is one of them:
.
/***********************************************************************/
/* */
/* G. Marsaglia and W. W. Tsang, */
/* "The 64-bit Universal RNG". */
/* Generates double precision floating-point random numbers. */
/* */
/* It produces uniform [0,1) variates directly, as 64-bit */
/* floating-point numbers, without conversion from integers. */
/* The resultant numbers have a very long period (2**202 or 10**61) */
/* with excellent randomness. The generator produces the same random */
/* numbers in IEEE machines, regardless of computer language used. */
/* */ /***********************************************************************/
/* Translated to PL/I from Fortran, by R. A. Vowels, 23 November 2005. */
(subscriptrange, fixedoverflow, size):
main: proc options (main);
declare x float binary (53), i fixed binary (31);
declare U(97) static float binary (53) external;
/* George Marsaglia & Wai Wan Tsang's 64-bit pseudo-random number generator */ uni64: procedure returns (float binary (53)) options(reorder);
declare r float binary (53) static initial
((9007199254740881.0e0 / 9007199254740992.e0));
declare d float binary (53) static initial
((362436069876.0e0 / 9007199254740992.0e0));
declare c float binary (53) static initial (0),
i fixed binary (7) static initial (97),
j fixed binary (7) static initial (33),
x float binary (53);
declare U(97) float binary (53) external;
x=U(i)-U(j); if x<0 then x=x+1.0; U(i)=x;
i = i - 1; if i=0 then i=97; j = j - 1; if j=0 then j=97;
c=c-d; if c<0 then c=c+r;
x=x-c; if x<0 then return (x+1.); return (x);
end uni64;
/* A two-seed function for filling the static array U(97) one bit at a time. */ fillU: procedure (seed1, seed2) options(reorder);
declare (seed1, seed2) fixed binary (31);
declare (s, t) float binary (53),
(x, y) fixed binary (31),
(i, j) fixed binary (7);
declare U(97) float binary (53) external;
x=seed1; y=seed2;
do i=1 to 97;
s=0.0; t=0.5;
do j=1 to 53;
(nofixedoverflow, nosize):
x=REM(6969*x, 65543);
(nofixedoverflow, nosize):
y=REM(8888*y, 65579);
if IAND(IEOR(x,y), 32)>0 then s=s+t;
t=.5*t;
end;
U(i)=s;
end;
end fillU;
call fillU (123456789,987654321);
do i=1 to 10000000; x=uni64(); end;
put skip list (' x x*9007199254740992.0');
do i=1 to 5;
x = uni64();
put skip edit(x, x*9007199254740992.0E0) (f(20,17), f(18));
end;
end main;
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)