Initial commit of fastrandom library
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 16 Nov 2017 16:20:15 +0000 (16:20 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 16 Nov 2017 16:20:15 +0000 (16:20 +0000)
tests/fastrandom/GNUmakefile [new file with mode: 0644]
tests/fastrandom/fastrandom.c [new file with mode: 0644]
tests/fastrandom/fastrandom.h [new file with mode: 0644]
tests/fastrandom/main.c [new file with mode: 0644]

diff --git a/tests/fastrandom/GNUmakefile b/tests/fastrandom/GNUmakefile
new file mode 100644 (file)
index 0000000..25577c9
--- /dev/null
@@ -0,0 +1,15 @@
+LIBS := -lc
+OBJS := fastrandom.o main.o
+CFLAGS += -Wall
+BIN := test
+
+all: $(BIN)
+
+%.o: %.c
+       cc -c ${CFLAGS} -I. -o $@ $<
+
+$(BIN): $(OBJS)
+       cc -o $@ $(OBJS) $(LIBS)
+
+clean:
+       rm -f $(BIN) $(OBJS)
diff --git a/tests/fastrandom/fastrandom.c b/tests/fastrandom/fastrandom.c
new file mode 100644 (file)
index 0000000..bb838d4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Fast multiple pseudorandom number states functions
+ * This can be useful where performance is critical and repeating low quality
+ * pseudorandom numbers are acceptable or even sought for.
+ *
+ * Copyright (c) 2017, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <fastrandom.h>
+
+/*
+ * Initializes specified random state.
+ * Returns 0, or EINVAL if parameters are invalid, ENOMEM if allocation fails.
+ * <state> fr_state_t object pointer to initialize.
+ * <seed> unsigned integer used to initialize random state using srand(3).
+ * <entries> amount of individual pseudorandom numbers in state table.
+ * <min>, <max> allowed random number range.
+ */
+int
+fr_init(fr_state_t *state, unsigned int seed, int entries, long min, long max)
+{
+       long    *ptr = NULL;
+
+       if (entries < 1 || min < 0 || max > RAND_MAX || min >= max)
+               return EINVAL;
+
+       if ((state->fr_start = malloc(sizeof(long) * entries)) == NULL)
+               return ENOMEM;
+
+       state->fr_cur = state->fr_start;
+       state->fr_end = &state->fr_start[entries];
+
+       srandom(seed);
+       for (ptr = state->fr_start, max; ptr < state->fr_end; ptr++)
+               *ptr = min + (random() % (max - min + 1));
+
+       return 0;
+}
+
+/*
+ * Returns a pseudorandom number using <state>.
+ * <state> must have previously been initialized once using fr_init().
+ */
+inline long
+fr_random(fr_state_t *state)
+{
+       register long   res;
+
+       res = *state->fr_cur++;
+       if (state->fr_cur == state->fr_end)
+               state->fr_cur = state->fr_start;
+
+       return res;
+}
diff --git a/tests/fastrandom/fastrandom.h b/tests/fastrandom/fastrandom.h
new file mode 100644 (file)
index 0000000..65f7cbd
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Fast multiple pseudorandom number states functions
+ * Copyright (c) 2017, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+#ifndef _FASTRANDOM_H_
+#define _FASTRANDOM_H_
+
+typedef struct fr_state {
+       long    *fr_start, *fr_end, *fr_cur;
+} fr_state_t;
+
+extern int             fr_init(fr_state_t *, unsigned int, int, long, long);
+inline extern long     fr_random(fr_state_t *);
+
+#endif
diff --git a/tests/fastrandom/main.c b/tests/fastrandom/main.c
new file mode 100644 (file)
index 0000000..760bb88
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <fastrandom.h>
+
+int    main(void);
+
+static fr_state_t      frs;
+
+int
+main(void)
+{
+       int     i;
+       long    min = 0, max = 15;
+
+       if (fr_init(&frs, (unsigned int)time(NULL), 16, min, max) != 0)
+               exit(EXIT_FAILURE);
+
+       for (i = 0, max = -RAND_MAX, min = RAND_MAX; i < 32; i++) {
+               long    r;
+
+               r = fr_random(&frs);
+               if (r < min)
+                       min = r;
+               if (r > max)
+                       max = r;
+               (void) printf("%ld\n", r);
+       }
+       (void) printf("min: %ld, max: %ld\n", min, max);
+
+       exit(EXIT_SUCCESS);
+}