random.c: reuse bits
* random.c (random_ulong_limited): reduce calling bytes methods by reusing dropped bits. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54969 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b402cc7161
commit
15fbd05e4e
16
random.c
16
random.c
@ -991,9 +991,21 @@ random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
|
|||||||
{
|
{
|
||||||
if (!limit) return 0;
|
if (!limit) return 0;
|
||||||
if (!rnd) {
|
if (!rnd) {
|
||||||
unsigned long val, mask = make_mask(limit);
|
const int w = sizeof(limit) * CHAR_BIT - nlz_long(limit);
|
||||||
|
const int n = w > 32 ? sizeof(unsigned long) : sizeof(uint32_t);
|
||||||
|
const unsigned long mask = ~(~0UL << w);
|
||||||
|
const unsigned long full = ~(~0UL << n * CHAR_BIT);
|
||||||
|
unsigned long val, bits = 0, rest = 0;
|
||||||
do {
|
do {
|
||||||
obj_random_bytes(obj, &val, sizeof(unsigned long));
|
if (mask & ~rest) {
|
||||||
|
union {uint32_t u32; unsigned long ul;} buf;
|
||||||
|
obj_random_bytes(obj, &buf, n);
|
||||||
|
rest = full;
|
||||||
|
bits = (n == sizeof(uint32_t)) ? buf.u32 : buf.ul;
|
||||||
|
}
|
||||||
|
val = bits;
|
||||||
|
bits >>= w;
|
||||||
|
rest >>= w;
|
||||||
val &= mask;
|
val &= mask;
|
||||||
} while (limit < val);
|
} while (limit < val);
|
||||||
return val;
|
return val;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user