-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom.c
212 lines (187 loc) · 5.04 KB
/
random.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/* random.c */
/* random3(): modified on 10/23/89 from random2() to generate positive ints*/
/* Modified again on 9/4/06 by Joel Dumke for VS .NET */
/* #include<pwd.h> */
#include <stdio.h>
//#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "stdafx.h"
#define MAXPRIME 2147483647 /* MAXPRIME = (2^31)-1 */
#define PI 3.14159265358979323846
/* PORTABILITY 1: The functions in this file assume that a long is 32 bits
and a short is 16 bits. These conventions are machine dependent and
must therefore be verified before using. */
static unsigned int sd[2],tmp; /* tmp: 31 bit seed in GF( (2^31)-1 ) */
/* sd[0]: high order 15 bits of tmp */
/* sd[1]: low order 16 bits of tmp */
/* NOTE: high order 16 bits of sd[0] and sd[1] are 0 */
/* Generates 20 random #'s starting from a seed of 1 */
/*
main()
{
int i;
int r,random3();
srandom2(1);
for(i=0;i<20;i++) {
r=random3();
printf("%d\n",r);
}
}
*/
/* TABLE: The following are the first 20 random #'s which should be generated
starting from a seed of 1:
16807
282475249
1622650073
984943658
1144108930
470211272
101027544
1457850878
1458777923
2007237709
823564440
1115438165
1784484492
74243042
114807987
1137522503
1441282327
16531729
823378840
143542612
*/
/* Test for verifying the cycle length of the random # generator */
/* NOTE: to speed up this test, comment out the return statement
in random2() */
/*
main()
{
double random2();
int i;
srandom2(1);
tmp=0;
while (tmp!=1) {
for(i=0;i<(256*256*256);i++) {
random2();
if (tmp == 1) break;
}
printf("*\n");
if (tmp == 0) break;
writeseed();
}
printf("\n%d\n",i);
writeseed();
}
*/
double random2()
/* Uniform random number generator on (0,1] */
/* Algorithm: newseed = (16807 * oldseed) MOD [(2^31) - 1] ;
returned value = newseed / ( (2^31)-1 ) ;
newseed is stored in tmp and sd[0] and sd[1] are updated;
Since 16807 is a primitive element of GF[(2^31)-1], repeated calls
to random2() should generate all positive integers <= MAXPRIME
before repeating any one value.
Tested: Feb. 16, 1988; verified the length of cycle of integers
generated by repeated calls to random2() */
{
*(sd+1) *= 16807;
*sd *= 16807;
tmp=((*sd)>>15)+(((*sd)&0x7fff)<<16);
tmp += (*(sd+1));
if ( tmp & 0x80000000 ) {
tmp++;
tmp &= 0x7fffffff;
}
*sd=tmp>>16;
*(sd+1)=tmp & 0xffff;
return(((double)tmp)/MAXPRIME);
}
int random3()
/* random3(): modified on 10/23/89 from random2() to generate positive ints*/
/* Uniform random number generator on (0,1] */
/* Algorithm: newseed = (16807 * oldseed) MOD [(2^31) - 1] ;
returned value = newseed / ( (2^31)-1 ) ;
newseed is stored in tmp and sd[0] and sd[1] are updated;
Since 16807 is a primitive element of GF[(2^31)-1], repeated calls
to random2() should generate all positive integers <= MAXPRIME
before repeating any one value.
Tested: Feb. 16, 1988; verified the length of cycle of integers
generated by repeated calls to random2() */
{
*(sd+1) *= 16807;
*sd *= 16807;
tmp=((*sd)>>15)+(((*sd)&0x7fff)<<16);
tmp += (*(sd+1));
if ( tmp & 0x80000000 ) {
tmp++;
tmp &= 0x7fffffff;
}
*sd=tmp>>16;
*(sd+1)=tmp & 0xffff;
return((int)tmp);
}
srandom2(unsigned int num)
/* Set a new seed for random # generator */
{
tmp=num;
*sd=tmp>>16;
*(sd+1)=tmp & 0xffff;
}
void readseed()
/* Reads random # generator seed from file: /tmp/randomseedmlc */
{
FILE *fopen(),*fp1;
char *calloc();
void writeseed();
if((fp1 = fopen("randomseedmlc","r"))==NULL ) {
fprintf(stderr,"readseed: creating file randomseedmlc\n");
tmp=143542612;
writeseed();
srandom2(tmp);
} else {
fscanf(fp1,"%d",&tmp);
srandom2(tmp);
fclose(fp1);
}
}
void writeseed()
/* Writes random # generator seed from file: /tmp/randomseedmlc */
{
FILE *fopen(),*fp1;
char *calloc();
if((fp1 = fopen("randomseedmlc","w"))==NULL ) {
fprintf(stderr,"writeseed: can't open file randomseedmlc\n");
exit(1);
} else {
fprintf(fp1,"%d",tmp);
fclose(fp1);
}
}
double normal()
/* Generates normal random numbers: N(0,1) */
{
static int even = 1; /* if even = 0: return b */
/* even = 1: compute 2 new values */
static double b; /* temporary storage */
double a,r,theta,random2();
if((even=!even)) {
return(b);
} else {
theta=2*PI*random2();
r=sqrt(-2*log(random2()));
a=r*cos(theta);
b=r*sin(theta);
return(a);
}
}
double dexprand()
/* Generates a double exponentially distributed random variable
with mean 0 and variance 2. */
{
double a,random2();
a= -log(random2());
if( random2()>0.5 ) a=(-a);
return(a);
}