From: Nobuyoshi Nakada Date: 2007-07-12T16:38:50+09:00 Subject: [ruby-dev:31193] Re: Random なかだです。 At Thu, 12 Jul 2007 15:49:36 +0900, NAKAMURA, Hiroshi wrote in [ruby-dev:31192]: > [ruby-dev:31184]のうささんによる修正も入れて、これで目に見えてる範囲の > 問題はなくなりましたね。 出遅れた感がありますが、警告の抑制とか細かいミスの修正とか。 --- random.c~ 2007-07-12 05:16:12.000000000 +0900 +++ random.c 2007-07-12 06:05:21.000000000 +0900 @@ -342,6 +342,5 @@ random_bytes(VALUE obj, VALUE len) int r; struct MT *mt; - unsigned char *ptr; - unsigned char *pend; + char *ptr, *pend; switch (TYPE(len)) { @@ -617,12 +616,12 @@ limited_fix_rand(struct MT *mt, unsigned static VALUE -limited_big_rand(struct MT *mt, struct RBignum *limit) +limited_big_rand(struct MT *mt, VALUE vmax) { unsigned long mask, lim, rnd; - struct RBignum *val; + struct RBignum *val, *limit = RB_GC_GUARD(vmax); int i, len, boundary; len = (limit->len * SIZEOF_BDIGITS + 3) / 4; - val = (struct RBignum *)rb_big_clone((VALUE)limit); + val = RBIGNUM(rb_big_clone(vmax)); val->sign = 1; #if SIZEOF_BDIGITS == 2 @@ -662,31 +661,26 @@ limited_big_rand(struct MT *mt, struct R static VALUE -limited_rand(struct MT *mt, VALUE *max) +limited_rand(struct MT *mt, VALUE vmax) { - VALUE vmax = *max; long lmax; if (FIXNUM_P(vmax)) { lmax = FIX2LONG(vmax) - 1; - fixnum: - if (lmax <= -1) { - rb_raise(rb_eArgError, "invalid domain"); - } - return LONG2NUM(limited_fix_rand(mt, lmax)); } else { - struct RBignum *limit; Check_Type(vmax, T_BIGNUM); - limit = (struct RBignum *)vmax; - if (!limit->sign) { + if (!RBIGNUM(vmax)->sign) { rb_raise(rb_eArgError, "invalid domain"); } - limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1)); - if (FIXNUM_P((VALUE)limit)) { - lmax = (VALUE)limit; - goto fixnum; + vmax = rb_big_minus(vmax, INT2FIX(1)); + if (!FIXNUM_P(vmax)) { + return limited_big_rand(mt, vmax); } - return limited_big_rand(mt, limit); + lmax = FIX2LONG(vmax); + } + if (lmax < 0) { + rb_raise(rb_eArgError, "invalid domain"); } + return ULONG2NUM(limited_fix_rand(mt, lmax)); } @@ -717,5 +711,5 @@ random_rand(int argc, VALUE *argv, VALUE rb_scan_args(argc, argv, "01", &vmax); if (NIL_P(vmax) || vmax == INT2FIX(0)) { - return rb_float_new(genrand_real_0(get_mt(obj))); + return rb_float_new(genrand_real_0(get_mt(obj))); } mt = get_mt(obj); @@ -768,5 +762,5 @@ random_rand(int argc, VALUE *argv, VALUE break; } - return limited_rand(mt, &vmax); + return limited_rand(mt, vmax); } @@ -808,5 +802,5 @@ random_integer(VALUE obj, VALUE vmax) rb_raise(rb_eArgError, "argument must be an integer"); } - return limited_rand(mt, &vmax); + return limited_rand(mt, vmax); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦