From 91a686d1f5fac8b0992eba17db94d3c8f76cdc65 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 22 Dec 2021 00:01:26 +0900 Subject: [PATCH] [util] Add mtwist float random number functions mtwist_rand_0_1 produces numbers in the range [0, 1) and mtwist_rand_m1_1 produces numbers in the range (-1, 1). The numbers will not be denormal, so the distribution should be fairly uniform (as much as Mersenne Twister itself is), but this needs proper testing. 0 is included for the mtwist_rand_0_1 as it seems useful, but -1 is not included in mtwist_rand_m1_1 in order to keep the extremes of the distribution balanced around 0. --- include/QF/mersenne.h | 40 ++++++++++++++++++++++++++++++++++++++++ libs/util/mersenne.c | 1 + 2 files changed, 41 insertions(+) diff --git a/include/QF/mersenne.h b/include/QF/mersenne.h index 197ded28d..d80b53e43 100644 --- a/include/QF/mersenne.h +++ b/include/QF/mersenne.h @@ -42,5 +42,45 @@ typedef struct { void mtwist_seed (mtstate_t *state, uint32_t seed); uint32_t mtwist_rand (mtstate_t *state); +GNU89INLINE inline float mtwist_rand_0_1 (mtstate_t *state); +GNU89INLINE inline float mtwist_rand_m1_1 (mtstate_t *state); + +#ifndef IMPLEMENT_MTWIST_Funcs +GNU89INLINE inline +#else +VISIBLE +#endif +float +mtwist_rand_0_1 (mtstate_t *state) +{ + union { + uint32_t u; + float f; + } uf; + + uf.u = mtwist_rand (state) & 0x007fffff; + uf.u |= 0x3f800000; + return uf.f - 1.0; +} + +#ifndef IMPLEMENT_MTWIST_Funcs +GNU89INLINE inline +#else +VISIBLE +#endif +float +mtwist_rand_m1_1 (mtstate_t *state) +{ + union { + uint32_t u; + float f; + } uf; + + do { + uf.u = mtwist_rand (state) & 0x007fffff; + } while (!uf.u); + uf.u |= 0x40000000; + return uf.f - 3.0; +} #endif//__QF_mersenne_h diff --git a/libs/util/mersenne.c b/libs/util/mersenne.c index 35794932b..5c0cbacbc 100644 --- a/libs/util/mersenne.c +++ b/libs/util/mersenne.c @@ -48,6 +48,7 @@ There were no differences. */ +#define IMPLEMENT_MTWIST_Funcs #include "QF/mersenne.h" #define KNUTH_MULT 1812433253ul // 0x6c078965