diff --git a/ChangeLog b/ChangeLog index 4e8fa65845..fd4eb82ba0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Oct 9 17:59:00 2012 Nobuyoshi Nakada + + * random.c (rb_random_ulong_limited): new function to return a random + value from 0 upto limit as unsigned long, simillary to + rb_genrand_ulong_limited but with arbitrary RNG object. + Tue Oct 9 17:13:27 2012 Nobuyoshi Nakada * process.c (rb_execarg_addopt, rb_execarg_run_options): add :uid and diff --git a/include/ruby/intern.h b/include/ruby/intern.h index eebb24ce0a..f954232b48 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -610,6 +610,7 @@ VALUE rb_random_bytes(VALUE rnd, long n); VALUE rb_random_int(VALUE rnd, VALUE max); unsigned int rb_random_int32(VALUE rnd); double rb_random_real(VALUE rnd); +unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit); unsigned long rb_genrand_ulong_limited(unsigned long i); /* re.c */ #define rb_memcmp memcmp diff --git a/random.c b/random.c index b36784c405..ccae2a0178 100644 --- a/random.c +++ b/random.c @@ -943,6 +943,22 @@ rb_random_real(VALUE obj) return genrand_real(&rnd->mt); } +unsigned long +rb_random_ulong_limited(VALUE obj, unsigned long limit) +{ + rb_random_t *rnd = try_get_rnd(obj); + if (!rnd) { + VALUE lim = ULONG2NUM(limit); + VALUE v = rb_funcall2(obj, id_rand, 1, &lim); + unsigned long r = NUM2ULONG(v); + if (r > limit) { + rb_raise(rb_eRangeError, "random number too big %ld", r); + } + return r; + } + return limited_rand(&rnd->mt, limit); +} + /* * call-seq: prng.bytes(size) -> a_string *