diff options
| -rw-r--r-- | examples/rngtest.c | 8 | ||||
| -rw-r--r-- | stc/crandom.h | 16 |
2 files changed, 22 insertions, 2 deletions
diff --git a/examples/rngtest.c b/examples/rngtest.c index ca037292..66e5f0c8 100644 --- a/examples/rngtest.c +++ b/examples/rngtest.c @@ -12,7 +12,12 @@ int main(void) {
clock_t difference, before;
uint64_t v;
- printf("start\n");
+
+ crandom_eng64_t sfc = crandom_eng64_init(time(NULL));
+ crandom_distrib_i64_t d10 = crandom_uniform_i64_init(10, 20);
+
+ for (int i=0; i<30; ++i) printf("%02zd ", crandom_uniform_i64(&sfc, d10));
+ puts("");
crandom_eng32_t pcg = crandom_eng32_init(time(NULL));
before = clock(); \
@@ -23,7 +28,6 @@ int main(void) difference = clock() - before;
printf("pcg32: %.02f, %zu\n", (float) difference / CLOCKS_PER_SEC, v);
- crandom_eng64_t sfc = crandom_eng64_init(time(NULL));
before = clock(); \
v = 0;
for (size_t i=0; i<NN; i++) {
diff --git a/stc/crandom.h b/stc/crandom.h index b73dd11b..cd6c98cd 100644 --- a/stc/crandom.h +++ b/stc/crandom.h @@ -73,6 +73,7 @@ STC_INLINE float crandom_uniform_f32(crandom_eng32_t* rng, crandom_distrib_f32_t typedef struct {uint64_t state[4];} crandom_eng64_t;
+typedef struct {int64_t offset, range;} crandom_distrib_i64_t;
typedef struct {double offset, range;} crandom_distrib_f64_t;
/* 64 bit random number generator engine */
@@ -89,6 +90,21 @@ STC_INLINE double crandom_f64(crandom_eng64_t* rng) { return u.f - 1.0;
}
+/* int random number generator in range [low, high] */
+STC_INLINE crandom_distrib_i64_t crandom_uniform_i64_init(int64_t low, int64_t high) {
+ crandom_distrib_i64_t dist = {low, high - low + 1}; return dist;
+}
+STC_INLINE int64_t crandom_uniform_i64(crandom_eng64_t* rng, crandom_distrib_i64_t dist) {
+#if defined(__SIZEOF_INT128__)
+ return dist.offset + (int64_t) (((__uint128_t) crandom_i64(rng) * dist.range) >> 64);
+#elif defined(_MSC_VER)
+ int64_t hi; _mul128(crandom_i64(rng) >> 1, dist.range << 1, &hi); return dist.offset + hi;
+#else
+ return dist.offset + (((uint32_t) crandom_i64(rng) * dist.range) >> 32); // range up to 2^32
+ //return dist.offset + crandom_i64(rng) % dist.range; // slow
+#endif
+}
+
STC_INLINE crandom_distrib_f64_t crandom_uniform_f64_init(double low, double high) {
crandom_distrib_f64_t dist = {low, high - low}; return dist;
}
|
