* bignum.c (big2str_base_powerof2): New function.

(rb_big2str0): Use big2str_base_powerof2 if base is 2, 4, 8, 16 or 32.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41194 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2013-06-09 00:36:58 +00:00
parent 4ff3b7cf05
commit f6757f080c
2 changed files with 42 additions and 0 deletions

View File

@ -1,3 +1,8 @@
Sun Jun 9 09:34:44 2013 Tanaka Akira <akr@fsij.org>
* 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@fsij.org>
* hash.c (rb_hash): Use rb_integer_pack to obtain least significant

View File

@ -1684,6 +1684,37 @@ calc_hbase(int base, BDIGIT *hbase_p, int *hbase_numdigits_p)
*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)
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);