diff options
Diffstat (limited to 'km-rand-erand48.c')
-rw-r--r-- | km-rand-erand48.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/km-rand-erand48.c b/km-rand-erand48.c new file mode 100644 index 0000000..de84b93 --- /dev/null +++ b/km-rand-erand48.c @@ -0,0 +1,89 @@ +#include <stdbool.h> // bool +#define _DEFAULT_SOURCE +#include <stdlib.h> // drand48_r() +#include <stdio.h> // fopen() +#include "util.h" +#include "km.h" + +// get N get_floats +static bool +on_get_floats( + km_rand_t * const rs, + const size_t num_vals, + float * const vals +) { + unsigned short * const data = rs->data; + + // generate results + for (size_t i = 0; i < num_vals; i++) { + vals[i] = erand48(data); + } + + // return success + return true; +} + +// fill sizes callback for system random source +static bool +on_get_sizes( + km_rand_t * const rs, + const size_t num_vals, + size_t * const vals +) { + unsigned short * const data = rs->data; + + // generate results + for (size_t i = 0; i < num_vals; i++) { + vals[i] = nrand48(data); + } + + // return success + return true; +} + +static void +on_fini( + km_rand_t * const rs +) { + unsigned short * data = rs->data; + + // free rng data + free(data); + + // clear pointer + rs->data = NULL; +} + +// path random source callbacks +static const km_rand_cbs_t +ERAND48_RAND_CBS = { + .get_floats = on_get_floats, + .get_sizes = on_get_sizes, + .fini = on_fini, +}; + +// init system random source (uses system rand()) +bool +km_rand_init_erand48( + km_rand_t * const rs, + const uint64_t seed +) { + // alloc rng data + unsigned short * const data = malloc(3 * sizeof(unsigned short)); + if (!data) { + // return failure + return false; + } + + // populate seed + data[0] = seed & 0xffff; + data[1] = (seed >> 16) & 0xffff; + data[2] = (seed >> 32) & 0xffff; + + // populate context + rs->cbs = &ERAND48_RAND_CBS; + rs->data = data; + + // return success + return true; +} |