aboutsummaryrefslogtreecommitdiff
path: root/lmathlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-02-27 12:59:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-02-27 12:59:22 -0300
commit6eb53b752617fae9e1329bfe2cfecdcbb593c398 (patch)
treec392ef632bbcfbf7b3716f5c6c17b06617bca8da /lmathlib.c
parent9b7987a9d1471ba94764286b28e0998f73deb46a (diff)
downloadlua-6eb53b752617fae9e1329bfe2cfecdcbb593c398.tar.gz
lua-6eb53b752617fae9e1329bfe2cfecdcbb593c398.tar.bz2
lua-6eb53b752617fae9e1329bfe2cfecdcbb593c398.zip
Details
Several details in code (e.g., moving a variable to the most inner scope that encloses its uses), comments, parameter names, extra tests.
Diffstat (limited to 'lmathlib.c')
-rw-r--r--lmathlib.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/lmathlib.c b/lmathlib.c
index 7197fc59..63f6036a 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -522,16 +522,18 @@ typedef struct {
522** Project the random integer 'ran' into the interval [0, n]. 522** Project the random integer 'ran' into the interval [0, n].
523** Because 'ran' has 2^B possible values, the projection can only be 523** Because 'ran' has 2^B possible values, the projection can only be
524** uniform when the size of the interval is a power of 2 (exact 524** uniform when the size of the interval is a power of 2 (exact
525** division). To get a uniform projection into [0, n], we first compute 525** division). Otherwise, to get a uniform projection into [0, n], we
526** 'lim', the smallest Mersenne number not smaller than 'n'. We then 526** first compute 'lim', the smallest Mersenne number not smaller than
527** project 'ran' into the interval [0, lim]. If the result is inside 527** 'n'. We then project 'ran' into the interval [0, lim]. If the result
528** [0, n], we are done. Otherwise, we try with another 'ran', until we 528** is inside [0, n], we are done. Otherwise, we try with another 'ran',
529** have a result inside the interval. 529** until we have a result inside the interval.
530*/ 530*/
531static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, 531static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
532 RanState *state) { 532 RanState *state) {
533 lua_Unsigned lim = n; 533 if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */
534 if ((lim & (lim + 1)) > 0) { /* 'lim + 1' is not a power of 2? */ 534 return ran & n; /* no bias */
535 else {
536 lua_Unsigned lim = n;
535 /* compute the smallest (2^b - 1) not smaller than 'n' */ 537 /* compute the smallest (2^b - 1) not smaller than 'n' */
536 lim |= (lim >> 1); 538 lim |= (lim >> 1);
537 lim |= (lim >> 2); 539 lim |= (lim >> 2);
@@ -541,13 +543,13 @@ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
541#if (LUA_MAXUNSIGNED >> 31) >= 3 543#if (LUA_MAXUNSIGNED >> 31) >= 3
542 lim |= (lim >> 32); /* integer type has more than 32 bits */ 544 lim |= (lim >> 32); /* integer type has more than 32 bits */
543#endif 545#endif
546 lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */
547 && lim >= n /* not smaller than 'n', */
548 && (lim >> 1) < n); /* and it is the smallest one */
549 while ((ran &= lim) > n) /* project 'ran' into [0..lim] */
550 ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */
551 return ran;
544 } 552 }
545 lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */
546 && lim >= n /* not smaller than 'n', */
547 && (lim == 0 || (lim >> 1) < n)); /* and it is the smallest one */
548 while ((ran &= lim) > n) /* project 'ran' into [0..lim] */
549 ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */
550 return ran;
551} 553}
552 554
553 555