[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]