From 82684a205c2849525ced5f463615f5e8acbcc6a2 Mon Sep 17 00:00:00 2001 From: amrali-eg <32075105+amrali-eg@users.noreply.github.com> Date: Mon, 28 Feb 2022 00:17:58 +0300 Subject: [PATCH] Non-uniform random floats (_randommodule.c) The original implementation produces an output that has some bias in the lower bits of mantissa (more 0's than 1's). That's because we try to fit 2^53 pigeons into 2^52 available holes, so rounding to even is unavoidable. My solution is to generate just 2^52 pigeons using the expression (randbits_53 | 1) to generate 2^52 odd numbers only in the range [1, 2^53-1] , with zero cannot be generated. but, the distribution of mantissa bits becomes more uniform. --- Modules/_randommodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index d96c0371ec7f8e..86e839d6010e92 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -177,7 +177,7 @@ _random_Random_random_impl(RandomObject *self) /*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ { uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6; - return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); + return PyFloat_FromDouble(((((uint64_t)(a)<<26)|b)|1)*(1.0/9007199254740992.0)); } /* initializes mt[N] with a seed */