ruby-changes:29142
From: akr <ko1@a...>
Date: Sun, 9 Jun 2013 09:37:08 +0900 (JST)
Subject: [ruby-changes:29142] akr:r41194 (trunk): * bignum.c (big2str_base_powerof2): New function.
akr 2013-06-09 09:36:58 +0900 (Sun, 09 Jun 2013) New Revision: 41194 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41194 Log: * bignum.c (big2str_base_powerof2): New function. (rb_big2str0): Use big2str_base_powerof2 if base is 2, 4, 8, 16 or 32. Modified files: trunk/ChangeLog trunk/bignum.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41193) +++ ChangeLog (revision 41194) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Jun 9 09:34:44 2013 Tanaka Akira <akr@f...> + + * bignum.c (big2str_base_powerof2): New function. + (rb_big2str0): Use big2str_base_powerof2 if base is 2, 4, 8, 16 or 32. + Sun Jun 9 00:59:04 2013 Tanaka Akira <akr@f...> * hash.c (rb_hash): Use rb_integer_pack to obtain least significant Index: bignum.c =================================================================== --- bignum.c (revision 41193) +++ bignum.c (revision 41194) @@ -1684,6 +1684,37 @@ calc_hbase(int base, BDIGIT *hbase_p, in https://github.com/ruby/ruby/blob/trunk/bignum.c#L1684 *hbase_numdigits_p = hbase_numdigits; } +static VALUE +big2str_base_powerof2(VALUE x, size_t len, int base, int trim) +{ + int word_numbits = ffs(base) - 1; + size_t numwords; + VALUE result; + char *ptr; + numwords = trim ? rb_absint_size_in_word(x, word_numbits, NULL) : len; + if (RBIGNUM_NEGATIVE_P(x) || !trim) { + if (LONG_MAX-1 < numwords) + rb_raise(rb_eArgError, "too big number"); + result = rb_usascii_str_new(0, 1+numwords); + ptr = RSTRING_PTR(result); + *ptr++ = RBIGNUM_POSITIVE_P(x) ? '+' : '-'; + } + else { + if (LONG_MAX < numwords) + rb_raise(rb_eArgError, "too big number"); + result = rb_usascii_str_new(0, numwords); + ptr = RSTRING_PTR(result); + } + rb_integer_pack(x, NULL, NULL, ptr, numwords, 1, CHAR_BIT-word_numbits, + INTEGER_PACK_BIG_ENDIAN); + while (0 < numwords) { + *ptr = ruby_digitmap[*(unsigned char *)ptr]; + ptr++; + numwords--; + } + return result; +} + VALUE rb_big2str0(VALUE x, int base, int trim) { @@ -1705,6 +1736,12 @@ rb_big2str0(VALUE x, int base, int trim) https://github.com/ruby/ruby/blob/trunk/bignum.c#L1736 rb_raise(rb_eArgError, "invalid radix %d", base); n2 = big2str_find_n1(x, base); + + if (base & (base - 1) == 0) { + /* base == 2 || base == 4 || base == 8 || base == 16 || base == 32 */ + return big2str_base_powerof2(x, (size_t)n2, base, trim); + } + n1 = (n2 + 1) / 2; ss = rb_usascii_str_new(0, n2 + 1); /* plus one for sign */ ptr = RSTRING_PTR(ss); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/