1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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:
nobu 2016-05-10 06:46:09 +00:00
parent b402cc7161
commit 15fbd05e4e

View file

@ -991,9 +991,21 @@ random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
{
if (!limit) return 0;
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 {
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;
} while (limit < val);
return val;