GRASS GIS 7 Programmer's Manual  7.0.2(2015)-r00000
lrand48.c
Go to the documentation of this file.
1 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18 
19 #include <grass/gis.h>
20 #include <grass/glocale.h>
21 
22 #ifdef HAVE_GETTIMEOFDAY
23 #include <sys/time.h>
24 #else
25 #include <time.h>
26 #endif
27 
28 #include <sys/types.h>
29 #include <unistd.h>
30 
31 typedef unsigned short uint16;
32 typedef unsigned int uint32;
33 typedef signed int int32;
34 
35 static uint16 x0, x1, x2;
36 static const uint32 a0 = 0xE66D;
37 static const uint32 a1 = 0xDEEC;
38 static const uint32 a2 = 0x5;
39 
40 static const uint32 b0 = 0xB;
41 
42 static int seeded;
43 
44 #define LO(x) ((x) & 0xFFFFU)
45 #define HI(x) ((x) >> 16)
46 
53 void G_srand48(long seedval)
54 {
55  uint32 x = (uint32) *(unsigned long *)&seedval;
56  x2 = (uint16) HI(x);
57  x1 = (uint16) LO(x);
58  x0 = (uint16) 0x330E;
59  seeded = 1;
60 }
61 
71 long G_srand48_auto(void)
72 {
73  unsigned long seed = (unsigned long) getpid();
74 
75 #ifdef HAVE_GETTIMEOFDAY
76  {
77  struct timeval tv;
78  if (gettimeofday(&tv, NULL) < 0)
79  G_fatal_error(_("gettimeofday failed: %s"), strerror(errno));
80  seed += (unsigned long) tv.tv_sec;
81  seed += (unsigned long) tv.tv_usec;
82  }
83 #else
84  {
85  time_t t = time(NULL);
86  seed += (unsigned long) t;
87  }
88 #endif
89 
90  G_srand48((long) seed);
91  return (long) seed;
92 }
93 
94 static void G__next(void)
95 {
96  uint32 a0x0 = a0 * x0;
97  uint32 a0x1 = a0 * x1;
98  uint32 a0x2 = a0 * x2;
99  uint32 a1x0 = a1 * x0;
100  uint32 a1x1 = a1 * x1;
101  uint32 a2x0 = a2 * x0;
102 
103  uint32 y0 = LO(a0x0) + b0;
104  uint32 y1 = LO(a0x1) + LO(a1x0) + HI(a0x0);
105  uint32 y2 = LO(a0x2) + LO(a1x1) + LO(a2x0) + HI(a0x1) + HI(a1x0);
106 
107  if (!seeded)
108  G_fatal_error(_("Pseudo-random number generator not seeded"));
109 
110  x0 = (uint16) LO(y0);
111  y1 += HI(y0);
112  x1 = (uint16) LO(y1);
113  y2 += HI(y1);
114  x2 = (uint16) LO(y2);
115 }
116 
123 long G_lrand48(void)
124 {
125  uint32 r;
126  G__next();
127  r = ((uint32) x2 << 15) | ((uint32) x1 >> 1);
128  return (long) r;
129 }
130 
137 long G_mrand48(void)
138 {
139  uint32 r;
140  G__next();
141  r = ((uint32) x2 << 16) | ((uint32) x1);
142  return (long) (int32) r;
143 }
144 
151 double G_drand48(void)
152 {
153  double r = 0.0;
154  G__next();
155  r += x2;
156  r *= 0x10000;
157  r += x1;
158  r *= 0x10000;
159  r += x0;
160  r /= 281474976710656.0; /* 2^48 */
161  return r;
162 }
163 
164 /*
165 
166 Test program
167 
168 int main(int argc, char **argv)
169 {
170  long s = (argc > 1) ? atol(argv[1]) : 0;
171  int i;
172 
173  srand48(s);
174  G_srand48(s);
175 
176  for (i = 0; i < 100; i++) {
177  printf("%.50f %.50f\n", drand48(), G_drand48());
178  printf("%lu %lu\n", lrand48(), G_lrand48());
179  printf("%ld %ld\n", mrand48(), G_mrand48());
180  }
181 
182  return 0;
183 }
184 
185 */
void G_srand48(long seedval)
Seed the pseudo-random number generator.
Definition: lrand48.c:53
long G_mrand48(void)
Generate an integer in the range [-2^31, 2^31)
Definition: lrand48.c:137
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
unsigned short uint16
Definition: lrand48.c:31
unsigned int uint32
Definition: lrand48.c:32
long G_lrand48(void)
Generate an integer in the range [0, 2^31)
Definition: lrand48.c:123
double t
#define LO(x)
Definition: lrand48.c:44
long G_srand48_auto(void)
Seed the pseudo-random number generator from the time and PID.
Definition: lrand48.c:71
signed int int32
Definition: lrand48.c:33
double r
double G_drand48(void)
Generate a floating-point value in the range [0,1)
Definition: lrand48.c:151
#define HI(x)
Definition: lrand48.c:45