alrand - a pseudo random number generation library
version 1.0.1
alrand is a library offering a generic interface to various random number
generation algorithms. It can be used both in thread safe mode (where the
user explicitely supplies the state to use) and in traditional mode, where
a global state is automatically maintained. Moreover, states are persistent
and can be saved and restored using predefined or user supplied load/save
routines.
The different generators supported by alrand have their own interface which can be used directly, as some generators have extra optional properties which are not available through the generic interface.
alrand's homepage can be found at http://lyrian.obnix.com/alrand/
alrand is Copyright 2002 Vincent Penquerc'h and is distributed under the terms of the Lesser General Public License (LGPL). See file LGPL.txt in the archive for more information.
#include <std_disclaimer.h>
"I do not accept responsibility for any effects, adverse or otherwise,
that this code may have on you, your computer, your sanity, your dog,
and anything else that you can think of. Use it at your own risk."
alrand does not require extra libraries besides the usual libc.
alrand is written in C, and should be compilable with any C compiler. It was written using GCC 2.95 on Linux. If you are using GCC and GNU make, then building is a very simple matter:
makeYou may also want to install the library:
make installor, if you want to install it somewhere else than /usr/local:
make install PREFIX=/home/user/alrand
alrand has a test program, which you can use to check that alrand is working correctly. You can run it this way:
make test
Using alrand is very simple: you need only include one file:
#include <alrand/alrand.h>and link against one library:
libalrand.a
If you wish to use directly the different generators, you will have to include its specific header:
You may want to use a specific generator directly to access some of their advanced properties: for instance, the Mersenne Twister algorithm can be seeded with 19937 bits of data, though the alrand generic interface only supports seeding with 32 bits of data.#include <alrand/mersenne.h>
Note that the algorithms used in alrand are not cryptographically secure. If you're looking for a cryptographic quality pseudo random number generator, you might want to have a look at Yarrow at http://www.counterpane.com/yarrow.html.
Following are some macros useful for allowing building with different versions of alrand.
ALRAND_MAJOR This is the major number of alrand's version. It is the x in x.y.z.
ALRAND_MINOR This is the minor number of alrand's version. It is the y in x.y.z.
ALRAND_PATCH This is the patch number of alrand's version. It is the z in x.y.z.
ALRAND_MAKE_VERSION This helper macro allows one to build a version number in the format of ALRAND_VERSION from the major, minor and patch numbers, ready to be tested against ALRAND_VERSION.
ALRAND_VERSION This is the patch number of alrand's version. It is a decimal number made up of the three version number components presented above. It is equal to ALRAND_VERSION * 10000 + ALRAND_MINOR * 100 + ALRAND_PATCH, which makes it easy to test if alrand x.y.z or newer is available with a simple comparison.
ALRAND_ID This text string identifies alrand and its version in a suitable form for displaying to the user.
See also: alrand_exit.
See also: alrand_init.
This interface allows access to the different generators supported by alrand using the same unified interface. Generators which expose extra information and/or configuration can be used through this interface, but these extra capabilities will be hidden. If you want to use them, you will have to access the appropriate generator directly through its own interface.
See also: alrand_generate, alrand_destroy, alrand_seed.
See also: alrand_create.
See also: alrand_create, alrand_generate.
See also: alrand_create, alrand_seed.
This interface uses a global generator, and is therefore not suitable for multithreaded programs unless appropriate care is taken (eg locking access to alrand, or ensuring that only one thread calls alrand, etc).
The global interface offers two API calls designed to mimic the standard C library calls srand and rand.
See also: alrand_rand, alrand_create.
See also: alrand_srand, alrand_generate.
See also: alrand_get_global_generator_type.
See also: alrand_set_global_generator_type.
alrand can save and restore a state using predefined routines or user defined ones. This allows a user program to ensure that a random number generator will yield the exact same stream of pseudo random numbers after being loaded as if it hadn't been saved and loaded back.
The generic routines to load and save a state take pointers to routines to save and load alrand_uint32_t data. alrand comes with sample routines and wrappers to use several different formats.
See also: alrand_load.
There are sample load/save routines supplied for convenience. Only one of
them (the Allegro one) is endianness independant (as it uses Allegro's
endian independant read/write routines). You may want to take these samples
as a guide to write load/save routines for the format you want.
Note that these sample routines are meant to be a guide, and do not include error checking, and are assuming sizes of certain data types. For instance, you should check for any errors (I/O, etc) after saving and loading states. They should be used as a starting point to build your own routines.
See also: alrand_save.
See also: alrand_save, alrand_load_from_fd.
See also: alrand_load, alrand_save_to_fd.
See also: alrand_save, alrand_load_from_stdio_file.
See also: alrand_load, alrand_save_to_stdio_file.
See also: alrand_save, alrand_load_from_allegro_packfile.
See also: alrand_load, alrand_save_to_allegro_packfile.
See also: alrand_save, alrand_load_from_gzfile.
See also: alrand_load, alrand_save_to_gzfile.
See also: alrand_save, alrand_load_from_bzfile.
See also: alrand_load, alrand_save_to_bzfile.
The Mersenne Twister was designed with the goal of overcoming the flaws found in many other pseudo random number generators, mainly the short period (the Mersenne Twister has a period of 2^19937-1) and the predictability of the distribution of generated numbers.
More info about the Mersenne Twister can be found at http://www.math.keio.ac.jp/~matumoto/emt.html.
Note: A Mersenne Twister generator state saves 626 32-bit words.
See also: alrand_mersenne_twister_seed, alrand_create, alrand_mersenne_twister_destroy.
See also: alrand_mersenne_twister_seed_v, alrand_mersenne_twister_create, alrand_mersenne_twister_generate.
See also: alrand_mersenne_twister_seed, alrand_mersenne_twister_create, alrand_mersenne_twister_generate.
See also: alrand_generate, alrand_mersenne_twister_create, alrand_mersenne_twister_seed, alrand_mersenne_twister_seed_v.
See also: alrand_destroy, alrand_mersenne_twister_create.
LCG is a very fast algorithm, but it has very weak randomness properties. However, it is often good enough for simple needs, as in most games. Each generated number is computed from the previous one (the original one being the seed) from the formula:
M and A being large primes. alrand's implementation uses an implicit T (2^32).x(n+1) = (x(n) * M + A) mod T
Is is to be noted that due to the fact that the state is 32 bit wide, the period of any LCG can't be more than 2^32, as once you generate the same number as a previous run, the same stream of numbers will follow. The period will also be different for each M,A pair. As a trivial example, the pair 1,0 yields a period of 1 (eg, all generated numbers are equal to the seed).
If you want to use different M,A pairs, you may use the mkprimes.c program supplied in the alrand archive. This program will print all primes smaller than a given number. By default, this number is 48*1024*1024, but you can increase it if you want. Just remember that the algorithm used here needs one bit of memory per number, so finding primes up to 48*1024*1024 requires 48 megabytes of memory. There is an easy optimization that checks only every second number, but since I didn't need it, I didn't bother. There are also other algorithms, but this one was the only one I knew offhand.
Note: A linear congruential generator state saves 4 32-bit words.
See also: alrand_create, alrand_lcg_create_custom, alrand_lcg_generate, alrand_lcg_destroy, alrand_lcg_seed.
See also: alrand_create, alrand_lcg_create, alrand_lcg_generate, alrand_lcg_destroy, alrand_lcg_seed.
See also: alrand_destroy, alrand_lcg_create.
See also: alrand_seed, alrand_lcg_create, alrand_lcg_create_custom.