ruby-changes:29125
From: akr <ko1@a...>
Date: Sat, 8 Jun 2013 21:06:10 +0900 (JST)
Subject: [ruby-changes:29125] akr:r41177 (trunk): * bignum.c (rb_absint_singlebit_p): New function.
akr 2013-06-08 21:05:57 +0900 (Sat, 08 Jun 2013) New Revision: 41177 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41177 Log: * bignum.c (rb_absint_singlebit_p): New function. * internal.h (rb_absint_singlebit_p): Declared. * time.c (v2w_bignum): Use rb_absint_singlebit_p instead of rb_big_abs_find_minbit. (rb_big_abs_find_minbit): Removed. Modified files: trunk/ChangeLog trunk/bignum.c trunk/internal.h trunk/time.c Index: time.c =================================================================== --- time.c (revision 41176) +++ time.c (revision 41177) @@ -313,25 +313,6 @@ rb_big_abs_find_maxbit(VALUE big) https://github.com/ruby/ruby/blob/trunk/time.c#L313 return res; } -static VALUE -rb_big_abs_find_minbit(VALUE big) -{ - BDIGIT *ds = RBIGNUM_DIGITS(big); - BDIGIT d; - long len = RBIGNUM_LEN(big); - long i; - VALUE res; - for (i = 0; i < len; i++) - if (ds[i]) - break; - if (i == len) - return Qnil; - res = mul(LONG2NUM(i), INT2FIX(SIZEOF_BDIGITS * CHAR_BIT)); - d = ds[i]; - res = add(res, LONG2FIX(ffs(d)-1)); - return res; -} - static wideval_t v2w_bignum(VALUE v) { @@ -346,8 +327,7 @@ v2w_bignum(VALUE v) https://github.com/ruby/ruby/blob/trunk/time.c#L327 return WINT2FIXWV(0); if (lt(maxbit, INT2FIX(sizeof(wideint_t) * CHAR_BIT - 2)) || (eq(maxbit, INT2FIX(sizeof(wideint_t) * CHAR_BIT - 2)) && - RBIGNUM_NEGATIVE_P(v) && - eq(rb_big_abs_find_minbit(v), INT2FIX(sizeof(wideint_t) * CHAR_BIT - 2)))) { + RBIGNUM_NEGATIVE_P(v) && rb_absint_singlebit_p(v))) { wideint_t i; i = 0; while (len) Index: ChangeLog =================================================================== --- ChangeLog (revision 41176) +++ ChangeLog (revision 41177) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Jun 8 21:03:40 2013 Tanaka Akira <akr@f...> + + * bignum.c (rb_absint_singlebit_p): New function. + + * internal.h (rb_absint_singlebit_p): Declared. + + * time.c (v2w_bignum): Use rb_absint_singlebit_p instead of + rb_big_abs_find_minbit. + (rb_big_abs_find_minbit): Removed. + Sat Jun 8 20:24:23 2013 Tanaka Akira <akr@f...> * time.c (rb_big_abs_find_maxbit): Use rb_absint_size. Index: internal.h =================================================================== --- internal.h (revision 41176) +++ internal.h (revision 41177) @@ -121,6 +121,7 @@ VALUE rb_integer_float_cmp(VALUE x, VALU https://github.com/ruby/ruby/blob/trunk/internal.h#L121 VALUE rb_integer_float_eq(VALUE x, VALUE y); size_t rb_absint_size(VALUE val, int *number_of_leading_zero_bits); size_t rb_absint_size_in_word(VALUE val, size_t word_numbits, size_t *number_of_leading_zero_bits); +int rb_absint_singlebit_p(VALUE val); /* class.c */ VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj); Index: bignum.c =================================================================== --- bignum.c (revision 41176) +++ bignum.c (revision 41177) @@ -537,6 +537,52 @@ rb_absint_size_in_word(VALUE val, size_t https://github.com/ruby/ruby/blob/trunk/bignum.c#L537 return numwords; } +int +rb_absint_singlebit_p(VALUE val) +{ + BDIGIT *dp; + BDIGIT *de; + BDIGIT fixbuf[(sizeof(long) + SIZEOF_BDIGITS - 1) / SIZEOF_BDIGITS]; + BDIGIT d; + + val = rb_to_int(val); + + if (FIXNUM_P(val)) { + long v = FIX2LONG(val); + if (v < 0) { + v = -v; + } +#if SIZEOF_BDIGITS == SIZEOF_LONG + fixbuf[0] = v; +#else + { + int i; + for (i = 0; i < numberof(fixbuf); i++) { + fixbuf[i] = (BDIGIT)(v & ((1L << (SIZEOF_BDIGITS * CHAR_BIT)) - 1)); + v >>= SIZEOF_BDIGITS * CHAR_BIT; + } + } +#endif + dp = fixbuf; + de = fixbuf + numberof(fixbuf); + } + else { + dp = BDIGITS(val); + de = dp + RBIGNUM_LEN(val); + } + while (dp < de && de[-1] == 0) + de--; + while (dp < de && dp[0] == 0) + dp++; + if (dp == de) /* no bit set. */ + return 0; + if (dp != de-1) /* two non-zero words. two bits set, at least. */ + return 0; + d = *dp; + d = d & (d - 1); /* Clear the least significant bit set */ + return d == 0; +} + #define INTEGER_PACK_WORDORDER_MASK \ (INTEGER_PACK_MSWORD_FIRST | \ INTEGER_PACK_LSWORD_FIRST) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/