grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

lrand48.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/lrand48.c
3 *
4 * \brief GIS Library - Pseudo-random number generation
5 *
6 * (C) 2014 by the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public License
9 * (>=v2). Read the file COPYING that comes with GRASS for details.
10 *
11 * \author Glynn Clements
12 */
13
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
31typedef unsigned short uint16;
32typedef unsigned int uint32;
33typedef signed int int32;
34
35static uint16 x0, x1, x2;
36static const uint32 a0 = 0xE66D;
37static const uint32 a1 = 0xDEEC;
38static const uint32 a2 = 0x5;
39
40static const uint32 b0 = 0xB;
41
42static int seeded;
43
44#define LO(x) ((x) & 0xFFFFU)
45#define HI(x) ((x) >> 16)
46
47/*!
48 * \brief Seed the pseudo-random number generator
49 *
50 * \param seedval 32-bit integer used to seed the PRNG
51 */
52
53void 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
62/*!
63 * \brief Seed the pseudo-random number generator from the time and PID
64 *
65 * A weak hash of the current time and PID is generated and used to
66 * seed the PRNG
67 *
68 * \return generated seed value passed to G_srand48()
69 */
70
72{
73 unsigned long seed;
74 char *grass_random_seed = getenv("GRASS_RANDOM_SEED");
75 if(grass_random_seed) {
76 seed = strtoull(grass_random_seed, NULL, 10);
77 } else {
78 seed = (unsigned long) getpid();
79
80#ifdef HAVE_GETTIMEOFDAY
81 {
82 struct timeval tv;
83 if (gettimeofday(&tv, NULL) < 0)
84 G_fatal_error(_("gettimeofday failed: %s"), strerror(errno));
85 seed += (unsigned long) tv.tv_sec;
86 seed += (unsigned long) tv.tv_usec;
87 }
88#else
89 {
90 time_t t = time(NULL);
91 seed += (unsigned long) t;
92 }
93#endif
94 }
95
96 G_srand48((long) seed);
97 return (long) seed;
98}
99
100static void G__next(void)
101{
102 uint32 a0x0 = a0 * x0;
103 uint32 a0x1 = a0 * x1;
104 uint32 a0x2 = a0 * x2;
105 uint32 a1x0 = a1 * x0;
106 uint32 a1x1 = a1 * x1;
107 uint32 a2x0 = a2 * x0;
108
109 uint32 y0 = LO(a0x0) + b0;
110 uint32 y1 = LO(a0x1) + LO(a1x0) + HI(a0x0);
111 uint32 y2 = LO(a0x2) + LO(a1x1) + LO(a2x0) + HI(a0x1) + HI(a1x0);
112
113 if (!seeded)
114 G_fatal_error(_("Pseudo-random number generator not seeded"));
115
116 x0 = (uint16) LO(y0);
117 y1 += HI(y0);
118 x1 = (uint16) LO(y1);
119 y2 += HI(y1);
120 x2 = (uint16) LO(y2);
121}
122
123/*!
124 * \brief Generate an integer in the range [0, 2^31)
125 *
126 * \return the generated value
127 */
128
129long G_lrand48(void)
130{
131 uint32 r;
132 G__next();
133 r = ((uint32) x2 << 15) | ((uint32) x1 >> 1);
134 return (long) r;
135}
136
137/*!
138 * \brief Generate an integer in the range [-2^31, 2^31)
139 *
140 * \return the generated value
141 */
142
143long G_mrand48(void)
144{
145 uint32 r;
146 G__next();
147 r = ((uint32) x2 << 16) | ((uint32) x1);
148 return (long) (int32) r;
149}
150
151/*!
152 * \brief Generate a floating-point value in the range [0,1)
153 *
154 * \return the generated value
155 */
156
157double G_drand48(void)
158{
159 double r = 0.0;
160 G__next();
161 r += x2;
162 r *= 0x10000;
163 r += x1;
164 r *= 0x10000;
165 r += x0;
166 r /= 281474976710656.0; /* 2^48 */
167 return r;
168}
169
170/*
171
172Test program
173
174int main(int argc, char **argv)
175{
176 long s = (argc > 1) ? atol(argv[1]) : 0;
177 int i;
178
179 srand48(s);
180 G_srand48(s);
181
182 for (i = 0; i < 100; i++) {
183 printf("%.50f %.50f\n", drand48(), G_drand48());
184 printf("%lu %lu\n", lrand48(), G_lrand48());
185 printf("%ld %ld\n", mrand48(), G_mrand48());
186 }
187
188 return 0;
189}
190
191*/
#define NULL
Definition: ccmath.h:32
char * getenv()
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: error.c:160
#define _(str)
Definition: glocale.h:13
unsigned short uint16
Definition: lrand48.c:31
unsigned int uint32
Definition: lrand48.c:32
static uint16 x0
Definition: lrand48.c:35
long G_mrand48(void)
Generate an integer in the range [-2^31, 2^31)
Definition: lrand48.c:143
long G_lrand48(void)
Generate an integer in the range [0, 2^31)
Definition: lrand48.c:129
static const uint32 a1
Definition: lrand48.c:37
static const uint32 a0
Definition: lrand48.c:36
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
#define HI(x)
Definition: lrand48.c:45
static void G__next(void)
Definition: lrand48.c:100
void G_srand48(long seedval)
Seed the pseudo-random number generator.
Definition: lrand48.c:53
static const uint32 a2
Definition: lrand48.c:38
static int seeded
Definition: lrand48.c:42
#define LO(x)
Definition: lrand48.c:44
static uint16 x1
Definition: lrand48.c:35
double G_drand48(void)
Generate a floating-point value in the range [0,1)
Definition: lrand48.c:157
static const uint32 b0
Definition: lrand48.c:40
static uint16 x2
Definition: lrand48.c:35
double t
Definition: r_raster.c:39
double r
Definition: r_raster.c:39
#define x