Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /* Originally developed and coded by Makoto Matsumoto and Takuji
21 : : * Nishimura. Please mail <matumoto@math.keio.ac.jp>, if you're using
22 : : * code from this file in your own programs or libraries.
23 : : * Further information on the Mersenne Twister can be found at
24 : : * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
25 : : * This code was adapted to glib by Sebastian Wilhelmi.
26 : : */
27 : :
28 : : /*
29 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
30 : : * file for a list of people on the GLib Team. See the ChangeLog
31 : : * files for a list of changes. These files are distributed with
32 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
33 : : */
34 : :
35 : : /*
36 : : * MT safe
37 : : */
38 : :
39 : : #include "config.h"
40 : : #define _CRT_RAND_S
41 : :
42 : : #include <math.h>
43 : : #include <errno.h>
44 : : #include <stdio.h>
45 : : #include <string.h>
46 : : #include <sys/types.h>
47 : : #include "grand.h"
48 : :
49 : : #include "genviron.h"
50 : : #include "gmain.h"
51 : : #include "gmem.h"
52 : : #include "gstdio.h"
53 : : #include "gtestutils.h"
54 : : #include "gthread.h"
55 : : #include "gtimer.h"
56 : :
57 : : #ifdef G_OS_UNIX
58 : : #include <fcntl.h>
59 : : #include <unistd.h>
60 : : #endif
61 : :
62 : : #ifdef G_OS_WIN32
63 : : #include <stdlib.h>
64 : : #include <process.h> /* For getpid() */
65 : : #endif
66 : :
67 : : /**
68 : : * GRand:
69 : : *
70 : : * The GRand struct is an opaque data structure. It should only be
71 : : * accessed through the g_rand_* functions.
72 : : **/
73 : :
74 : : G_LOCK_DEFINE_STATIC (global_random);
75 : :
76 : : /* Period parameters */
77 : : #define N 624
78 : : #define M 397
79 : : #define MATRIX_A 0x9908b0df /* constant vector a */
80 : : #define UPPER_MASK 0x80000000 /* most significant w-r bits */
81 : : #define LOWER_MASK 0x7fffffff /* least significant r bits */
82 : :
83 : : /* Tempering parameters */
84 : : #define TEMPERING_MASK_B 0x9d2c5680
85 : : #define TEMPERING_MASK_C 0xefc60000
86 : : #define TEMPERING_SHIFT_U(y) (y >> 11)
87 : : #define TEMPERING_SHIFT_S(y) (y << 7)
88 : : #define TEMPERING_SHIFT_T(y) (y << 15)
89 : : #define TEMPERING_SHIFT_L(y) (y >> 18)
90 : :
91 : : static guint
92 : 87884990 : get_random_version (void)
93 : : {
94 : : static gsize initialized = FALSE;
95 : : static guint random_version;
96 : :
97 : 87884990 : if (g_once_init_enter (&initialized))
98 : : {
99 : 681 : const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
100 : 681 : if (!version_string || version_string[0] == '\000' ||
101 : 0 : strcmp (version_string, "2.2") == 0)
102 : 681 : random_version = 22;
103 : 0 : else if (strcmp (version_string, "2.0") == 0)
104 : 0 : random_version = 20;
105 : : else
106 : : {
107 : 0 : g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
108 : : version_string);
109 : 0 : random_version = 22;
110 : : }
111 : 681 : g_once_init_leave (&initialized, TRUE);
112 : : }
113 : :
114 : 87884990 : return random_version;
115 : : }
116 : :
117 : : struct _GRand
118 : : {
119 : : guint32 mt[N]; /* the array for the state vector */
120 : : guint mti;
121 : : };
122 : :
123 : : /**
124 : : * g_rand_new_with_seed: (constructor)
125 : : * @seed: a value to initialize the random number generator
126 : : *
127 : : * Creates a new random number generator initialized with @seed.
128 : : *
129 : : * Returns: (transfer full): the new #GRand
130 : : **/
131 : : GRand*
132 : 84712 : g_rand_new_with_seed (guint32 seed)
133 : : {
134 : 84712 : GRand *rand = g_new0 (GRand, 1);
135 : 84712 : g_rand_set_seed (rand, seed);
136 : 84712 : return rand;
137 : : }
138 : :
139 : : /**
140 : : * g_rand_new_with_seed_array: (constructor)
141 : : * @seed: an array of seeds to initialize the random number generator
142 : : * @seed_length: an array of seeds to initialize the random number
143 : : * generator
144 : : *
145 : : * Creates a new random number generator initialized with @seed.
146 : : *
147 : : * Returns: (transfer full): the new #GRand
148 : : *
149 : : * Since: 2.4
150 : : */
151 : : GRand*
152 : 9295 : g_rand_new_with_seed_array (const guint32 *seed,
153 : : guint seed_length)
154 : : {
155 : 9295 : GRand *rand = g_new0 (GRand, 1);
156 : 9295 : g_rand_set_seed_array (rand, seed, seed_length);
157 : 9295 : return rand;
158 : : }
159 : :
160 : : /**
161 : : * g_rand_new: (constructor)
162 : : *
163 : : * Creates a new random number generator initialized with a seed taken
164 : : * either from `/dev/urandom` (if existing) or from the current time
165 : : * (as a fallback).
166 : : *
167 : : * On Windows, the seed is taken from rand_s().
168 : : *
169 : : * Returns: (transfer full): the new #GRand
170 : : */
171 : : GRand*
172 : 1295 : g_rand_new (void)
173 : : {
174 : : guint32 seed[4];
175 : : #ifdef G_OS_UNIX
176 : : static gboolean dev_urandom_exists = TRUE;
177 : :
178 : 1295 : if (dev_urandom_exists)
179 : : {
180 : : int dev_urandom;
181 : :
182 : : do
183 : 1295 : dev_urandom = g_open ("/dev/urandom", O_RDONLY | O_CLOEXEC);
184 : 1295 : while G_UNLIKELY (dev_urandom < 0 && errno == EINTR);
185 : :
186 : 1295 : if (dev_urandom >= 0)
187 : : {
188 : : ssize_t r;
189 : :
190 : : do
191 : 1295 : r = read (dev_urandom, seed, sizeof (seed));
192 : 1295 : while G_UNLIKELY (r < 0 && errno == EINTR);
193 : :
194 : 1295 : if (r != sizeof (seed))
195 : 0 : dev_urandom_exists = FALSE;
196 : :
197 : 1295 : close (dev_urandom);
198 : : }
199 : : else
200 : 0 : dev_urandom_exists = FALSE;
201 : : }
202 : :
203 : 1295 : if (!dev_urandom_exists)
204 : : {
205 : 0 : gint64 now_us = g_get_real_time ();
206 : 0 : seed[0] = (guint32) (now_us / G_USEC_PER_SEC);
207 : 0 : seed[1] = now_us % G_USEC_PER_SEC;
208 : 0 : seed[2] = getpid ();
209 : 0 : seed[3] = getppid ();
210 : : }
211 : : #else /* G_OS_WIN32 */
212 : : /* rand_s() is only available since Visual Studio 2005 and
213 : : * MinGW-w64 has a wrapper that will emulate rand_s() if it's not in msvcrt
214 : : */
215 : : #if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__MINGW64_VERSION_MAJOR)
216 : : gsize i;
217 : :
218 : : for (i = 0; i < G_N_ELEMENTS (seed); i++)
219 : : rand_s (&seed[i]);
220 : : #else
221 : : #warning Using insecure seed for random number generation because of missing rand_s() in Windows XP
222 : : GTimeVal now;
223 : :
224 : : g_get_current_time (&now);
225 : : seed[0] = now.tv_sec;
226 : : seed[1] = now.tv_usec;
227 : : seed[2] = getpid ();
228 : : seed[3] = 0;
229 : : #endif
230 : :
231 : : #endif
232 : :
233 : 1295 : return g_rand_new_with_seed_array (seed, 4);
234 : : }
235 : :
236 : : /**
237 : : * g_rand_free:
238 : : * @rand_: a #GRand
239 : : *
240 : : * Frees the memory allocated for the #GRand.
241 : : */
242 : : void
243 : 93242 : g_rand_free (GRand *rand)
244 : : {
245 : 93242 : g_return_if_fail (rand != NULL);
246 : :
247 : 93242 : g_free (rand);
248 : : }
249 : :
250 : : /**
251 : : * g_rand_copy:
252 : : * @rand_: a #GRand
253 : : *
254 : : * Copies a #GRand into a new one with the same exact state as before.
255 : : * This way you can take a snapshot of the random number generator for
256 : : * replaying later.
257 : : *
258 : : * Returns: (transfer full): the new #GRand
259 : : *
260 : : * Since: 2.4
261 : : */
262 : : GRand*
263 : 2 : g_rand_copy (GRand *rand)
264 : : {
265 : : GRand* new_rand;
266 : :
267 : 2 : g_return_val_if_fail (rand != NULL, NULL);
268 : :
269 : 2 : new_rand = g_new0 (GRand, 1);
270 : 2 : memcpy (new_rand, rand, sizeof (GRand));
271 : :
272 : 2 : return new_rand;
273 : : }
274 : :
275 : : /**
276 : : * g_rand_set_seed:
277 : : * @rand_: a #GRand
278 : : * @seed: a value to reinitialize the random number generator
279 : : *
280 : : * Sets the seed for the random number generator #GRand to @seed.
281 : : */
282 : : void
283 : 344021 : g_rand_set_seed (GRand *rand,
284 : : guint32 seed)
285 : : {
286 : 344021 : g_return_if_fail (rand != NULL);
287 : :
288 : 344021 : switch (get_random_version ())
289 : : {
290 : 0 : case 20:
291 : : /* setting initial seeds to mt[N] using */
292 : : /* the generator Line 25 of Table 1 in */
293 : : /* [KNUTH 1981, The Art of Computer Programming */
294 : : /* Vol. 2 (2nd Ed.), pp102] */
295 : :
296 : 0 : if (seed == 0) /* This would make the PRNG produce only zeros */
297 : 0 : seed = 0x6b842128; /* Just set it to another number */
298 : :
299 : 0 : rand->mt[0]= seed;
300 : 0 : for (rand->mti=1; rand->mti<N; rand->mti++)
301 : 0 : rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
302 : :
303 : 0 : break;
304 : 344021 : case 22:
305 : : /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
306 : : /* In the previous version (see above), MSBs of the */
307 : : /* seed affect only MSBs of the array mt[]. */
308 : :
309 : 344021 : rand->mt[0]= seed;
310 : 214669104 : for (rand->mti=1; rand->mti<N; rand->mti++)
311 : 214325083 : rand->mt[rand->mti] = 1812433253UL *
312 : 214325083 : (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti;
313 : 344021 : break;
314 : 0 : default:
315 : : g_assert_not_reached ();
316 : : }
317 : : }
318 : :
319 : : /**
320 : : * g_rand_set_seed_array:
321 : : * @rand_: a #GRand
322 : : * @seed: array to initialize with
323 : : * @seed_length: length of array
324 : : *
325 : : * Initializes the random number generator by an array of longs.
326 : : * Array can be of arbitrary size, though only the first 624 values
327 : : * are taken. This function is useful if you have many low entropy
328 : : * seeds, or if you require more then 32 bits of actual entropy for
329 : : * your application.
330 : : *
331 : : * Since: 2.4
332 : : */
333 : : void
334 : 9296 : g_rand_set_seed_array (GRand *rand,
335 : : const guint32 *seed,
336 : : guint seed_length)
337 : : {
338 : : guint i, j, k;
339 : :
340 : 9296 : g_return_if_fail (rand != NULL);
341 : 9296 : g_return_if_fail (seed_length >= 1);
342 : :
343 : 9296 : g_rand_set_seed (rand, 19650218UL);
344 : :
345 : 9296 : i=1; j=0;
346 : 9296 : k = (N>seed_length ? N : seed_length);
347 : 5810000 : for (; k; k--)
348 : : {
349 : 5800704 : rand->mt[i] = (rand->mt[i] ^
350 : 5800704 : ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL))
351 : 5800704 : + seed[j] + j; /* non linear */
352 : 5800704 : rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
353 : 5800704 : i++; j++;
354 : 5800704 : if (i>=N)
355 : : {
356 : 9296 : rand->mt[0] = rand->mt[N-1];
357 : 9296 : i=1;
358 : : }
359 : 5800704 : if (j>=seed_length)
360 : 1450696 : j=0;
361 : : }
362 : 5800704 : for (k=N-1; k; k--)
363 : : {
364 : 5791408 : rand->mt[i] = (rand->mt[i] ^
365 : 5791408 : ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL))
366 : 5791408 : - i; /* non linear */
367 : 5791408 : rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
368 : 5791408 : i++;
369 : 5791408 : if (i>=N)
370 : : {
371 : 9296 : rand->mt[0] = rand->mt[N-1];
372 : 9296 : i=1;
373 : : }
374 : : }
375 : :
376 : 9296 : rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
377 : : }
378 : :
379 : : /**
380 : : * g_rand_boolean:
381 : : * @rand_: a #GRand
382 : : *
383 : : * Returns a random #gboolean from @rand_.
384 : : * This corresponds to an unbiased coin toss.
385 : : *
386 : : * Returns: a random #gboolean
387 : : */
388 : : /**
389 : : * g_rand_int:
390 : : * @rand_: a #GRand
391 : : *
392 : : * Returns the next random #guint32 from @rand_ equally distributed over
393 : : * the range [0..2^32-1].
394 : : *
395 : : * Returns: a random number
396 : : */
397 : : guint32
398 : 274078616 : g_rand_int (GRand *rand)
399 : : {
400 : : guint32 y;
401 : : static const guint32 mag01[2]={0x0, MATRIX_A};
402 : : /* mag01[x] = x * MATRIX_A for x=0,1 */
403 : :
404 : 274078616 : g_return_val_if_fail (rand != NULL, 0);
405 : :
406 : 274078616 : if (rand->mti >= N) { /* generate N words at one time */
407 : : int kk;
408 : :
409 : 168782016 : for (kk = 0; kk < N - M; kk++) {
410 : 168041744 : y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
411 : 168041744 : rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
412 : : }
413 : 293887984 : for (; kk < N - 1; kk++) {
414 : 293147712 : y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
415 : 293147712 : rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
416 : : }
417 : 740272 : y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
418 : 740272 : rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
419 : :
420 : 740272 : rand->mti = 0;
421 : : }
422 : :
423 : 274078616 : y = rand->mt[rand->mti++];
424 : 274078616 : y ^= TEMPERING_SHIFT_U(y);
425 : 274078616 : y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
426 : 274078616 : y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
427 : 274078616 : y ^= TEMPERING_SHIFT_L(y);
428 : :
429 : 274078616 : return y;
430 : : }
431 : :
432 : : /* transform [0..2^32] -> [0..1] */
433 : : #define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
434 : :
435 : : /**
436 : : * g_rand_int_range:
437 : : * @rand_: a #GRand
438 : : * @begin: lower closed bound of the interval
439 : : * @end: upper open bound of the interval
440 : : *
441 : : * Returns the next random #gint32 from @rand_ equally distributed over
442 : : * the range [@begin..@end-1].
443 : : *
444 : : * Returns: a random number
445 : : */
446 : : gint32
447 : 87540969 : g_rand_int_range (GRand *rand,
448 : : gint32 begin,
449 : : gint32 end)
450 : : {
451 : 87540969 : guint32 dist = end - begin;
452 : 87540969 : guint32 random = 0;
453 : :
454 : 87540969 : g_return_val_if_fail (rand != NULL, begin);
455 : 87540969 : g_return_val_if_fail (end > begin, begin);
456 : :
457 : 87540969 : switch (get_random_version ())
458 : : {
459 : 0 : case 20:
460 : 0 : if (dist <= 0x10000L) /* 2^16 */
461 : : {
462 : : /* This method, which only calls g_rand_int once is only good
463 : : * for (end - begin) <= 2^16, because we only have 32 bits set
464 : : * from the one call to g_rand_int ().
465 : : *
466 : : * We are using (trans + trans * trans), because g_rand_int only
467 : : * covers [0..2^32-1] and thus g_rand_int * trans only covers
468 : : * [0..1-2^-32], but the biggest double < 1 is 1-2^-52.
469 : : */
470 : :
471 : 0 : gdouble double_rand = g_rand_int (rand) *
472 : : (G_RAND_DOUBLE_TRANSFORM +
473 : : G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
474 : :
475 : 0 : random = (gint32) (double_rand * dist);
476 : : }
477 : : else
478 : : {
479 : : /* Now we use g_rand_double_range (), which will set 52 bits
480 : : * for us, so that it is safe to round and still get a decent
481 : : * distribution
482 : : */
483 : 0 : random = (gint32) g_rand_double_range (rand, 0, dist);
484 : : }
485 : 0 : break;
486 : 87540969 : case 22:
487 : 87540969 : if (dist == 0)
488 : 0 : random = 0;
489 : : else
490 : : {
491 : : /* maxvalue is set to the predecessor of the greatest
492 : : * multiple of dist less or equal 2^32.
493 : : */
494 : : guint32 maxvalue;
495 : 87540969 : if (dist <= 0x80000000u) /* 2^31 */
496 : : {
497 : : /* maxvalue = 2^32 - 1 - (2^32 % dist) */
498 : 87540969 : guint32 leftover = (0x80000000u % dist) * 2;
499 : 87540969 : if (leftover >= dist) leftover -= dist;
500 : 87540969 : maxvalue = 0xffffffffu - leftover;
501 : : }
502 : : else
503 : 0 : maxvalue = dist - 1;
504 : :
505 : : do
506 : 87540976 : random = g_rand_int (rand);
507 : 87540976 : while (random > maxvalue);
508 : :
509 : 87540969 : random %= dist;
510 : : }
511 : 87540969 : break;
512 : 0 : default:
513 : : g_assert_not_reached ();
514 : : }
515 : :
516 : 87540969 : return begin + random;
517 : : }
518 : :
519 : : /**
520 : : * g_rand_double:
521 : : * @rand_: a #GRand
522 : : *
523 : : * Returns the next random #gdouble from @rand_ equally distributed over
524 : : * the range [0..1).
525 : : *
526 : : * Returns: a random number
527 : : */
528 : : gdouble
529 : 65458056 : g_rand_double (GRand *rand)
530 : : {
531 : : /* We set all 52 bits after the point for this, not only the first
532 : : 32. That's why we need two calls to g_rand_int */
533 : 65458056 : gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
534 : 65458056 : retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
535 : :
536 : : /* The following might happen due to very bad rounding luck, but
537 : : * actually this should be more than rare, we just try again then */
538 : 65458056 : if (retval >= 1.0)
539 : 0 : return g_rand_double (rand);
540 : :
541 : 65458056 : return retval;
542 : : }
543 : :
544 : : /**
545 : : * g_rand_double_range:
546 : : * @rand_: a #GRand
547 : : * @begin: lower closed bound of the interval
548 : : * @end: upper open bound of the interval
549 : : *
550 : : * Returns the next random #gdouble from @rand_ equally distributed over
551 : : * the range [@begin..@end).
552 : : *
553 : : * Returns: a random number
554 : : */
555 : : gdouble
556 : 64819452 : g_rand_double_range (GRand *rand,
557 : : gdouble begin,
558 : : gdouble end)
559 : : {
560 : : gdouble r;
561 : :
562 : 64819452 : r = g_rand_double (rand);
563 : :
564 : 64819452 : return r * end - (r - 1) * begin;
565 : : }
566 : :
567 : : static GRand *
568 : 26541104 : get_global_random (void)
569 : : {
570 : : static GRand *global_random;
571 : :
572 : : /* called while locked */
573 : 26541104 : if (!global_random)
574 : 681 : global_random = g_rand_new ();
575 : :
576 : 26541104 : return global_random;
577 : : }
578 : :
579 : : /**
580 : : * g_random_boolean:
581 : : *
582 : : * Returns a random #gboolean.
583 : : * This corresponds to an unbiased coin toss.
584 : : *
585 : : * Returns: a random #gboolean
586 : : */
587 : : /**
588 : : * g_random_int:
589 : : *
590 : : * Return a random #guint32 equally distributed over the range
591 : : * [0..2^32-1].
592 : : *
593 : : * Returns: a random number
594 : : */
595 : : guint32
596 : 16635737 : g_random_int (void)
597 : : {
598 : : guint32 result;
599 : 16635737 : G_LOCK (global_random);
600 : 16635737 : result = g_rand_int (get_global_random ());
601 : 16635737 : G_UNLOCK (global_random);
602 : 16635737 : return result;
603 : : }
604 : :
605 : : /**
606 : : * g_random_int_range:
607 : : * @begin: lower closed bound of the interval
608 : : * @end: upper open bound of the interval
609 : : *
610 : : * Returns a random #gint32 equally distributed over the range
611 : : * [@begin..@end-1].
612 : : *
613 : : * Returns: a random number
614 : : */
615 : : gint32
616 : 9399424 : g_random_int_range (gint32 begin,
617 : : gint32 end)
618 : : {
619 : : gint32 result;
620 : 9399424 : G_LOCK (global_random);
621 : 9399424 : result = g_rand_int_range (get_global_random (), begin, end);
622 : 9399424 : G_UNLOCK (global_random);
623 : 9399424 : return result;
624 : : }
625 : :
626 : : /**
627 : : * g_random_double:
628 : : *
629 : : * Returns a random #gdouble equally distributed over the range [0..1).
630 : : *
631 : : * Returns: a random number
632 : : */
633 : : gdouble
634 : 155931 : g_random_double (void)
635 : : {
636 : : double result;
637 : 155931 : G_LOCK (global_random);
638 : 155931 : result = g_rand_double (get_global_random ());
639 : 155931 : G_UNLOCK (global_random);
640 : 155931 : return result;
641 : : }
642 : :
643 : : /**
644 : : * g_random_double_range:
645 : : * @begin: lower closed bound of the interval
646 : : * @end: upper open bound of the interval
647 : : *
648 : : * Returns a random #gdouble equally distributed over the range
649 : : * [@begin..@end).
650 : : *
651 : : * Returns: a random number
652 : : */
653 : : gdouble
654 : 100000 : g_random_double_range (gdouble begin,
655 : : gdouble end)
656 : : {
657 : : double result;
658 : 100000 : G_LOCK (global_random);
659 : 100000 : result = g_rand_double_range (get_global_random (), begin, end);
660 : 100000 : G_UNLOCK (global_random);
661 : 100000 : return result;
662 : : }
663 : :
664 : : /**
665 : : * g_random_set_seed:
666 : : * @seed: a value to reinitialize the global random number generator
667 : : *
668 : : * Sets the seed for the global random number generator, which is used
669 : : * by the g_random_* functions, to @seed.
670 : : */
671 : : void
672 : 250012 : g_random_set_seed (guint32 seed)
673 : : {
674 : 250012 : G_LOCK (global_random);
675 : 250012 : g_rand_set_seed (get_global_random (), seed);
676 : 250012 : G_UNLOCK (global_random);
677 : 250012 : }
|