From 6eb53b752617fae9e1329bfe2cfecdcbb593c398 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 27 Feb 2020 12:59:22 -0300 Subject: Details Several details in code (e.g., moving a variable to the most inner scope that encloses its uses), comments, parameter names, extra tests. --- lmathlib.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'lmathlib.c') diff --git a/lmathlib.c b/lmathlib.c index 7197fc59..63f6036a 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -522,16 +522,18 @@ typedef struct { ** Project the random integer 'ran' into the interval [0, n]. ** Because 'ran' has 2^B possible values, the projection can only be ** uniform when the size of the interval is a power of 2 (exact -** division). To get a uniform projection into [0, n], we first compute -** 'lim', the smallest Mersenne number not smaller than 'n'. We then -** project 'ran' into the interval [0, lim]. If the result is inside -** [0, n], we are done. Otherwise, we try with another 'ran', until we -** have a result inside the interval. +** division). Otherwise, to get a uniform projection into [0, n], we +** first compute 'lim', the smallest Mersenne number not smaller than +** 'n'. We then project 'ran' into the interval [0, lim]. If the result +** is inside [0, n], we are done. Otherwise, we try with another 'ran', +** until we have a result inside the interval. */ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, RanState *state) { - lua_Unsigned lim = n; - if ((lim & (lim + 1)) > 0) { /* 'lim + 1' is not a power of 2? */ + if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ + return ran & n; /* no bias */ + else { + lua_Unsigned lim = n; /* compute the smallest (2^b - 1) not smaller than 'n' */ lim |= (lim >> 1); lim |= (lim >> 2); @@ -541,13 +543,13 @@ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, #if (LUA_MAXUNSIGNED >> 31) >= 3 lim |= (lim >> 32); /* integer type has more than 32 bits */ #endif + lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ + && lim >= n /* not smaller than 'n', */ + && (lim >> 1) < n); /* and it is the smallest one */ + while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ + ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ + return ran; } - lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ - && lim >= n /* not smaller than 'n', */ - && (lim == 0 || (lim >> 1) < n)); /* and it is the smallest one */ - while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ - ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ - return ran; } -- cgit v1.2.3-55-g6feb