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

ruby-changes:30683

From: akr <ko1@a...>
Date: Sun, 1 Sep 2013 23:34:59 +0900 (JST)
Subject: [ruby-changes:30683] akr:r42762 (trunk): * bignum.c (GMP_BIG2STR_DIGITS): New constant.

akr	2013-09-01 23:34:53 +0900 (Sun, 01 Sep 2013)

  New Revision: 42762

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42762

  Log:
    * bignum.c (GMP_BIG2STR_DIGITS): New constant.
      (big2str_gmp): New function.
      (rb_big2str1): Use big2str_gmp for big bignums.
    
    * internal.h (rb_big2str_gmp): Declared.
    
    * ext/-test-/bignum/big2str.c (big2str_gmp): New method.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c
    trunk/ext/-test-/bignum/big2str.c
    trunk/internal.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42761)
+++ ChangeLog	(revision 42762)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Sep  1 23:30:47 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (GMP_BIG2STR_DIGITS): New constant.
+	  (big2str_gmp): New function.
+	  (rb_big2str1): Use big2str_gmp for big bignums.
+
+	* internal.h (rb_big2str_gmp): Declared.
+
+	* ext/-test-/bignum/big2str.c (big2str_gmp): New method.
+
 Sun Sep  1 22:37:51 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (bary_mul_gmp): Use mpz_init and mpz_clear instead of
Index: ext/-test-/bignum/big2str.c
===================================================================
--- ext/-test-/bignum/big2str.c	(revision 42761)
+++ ext/-test-/bignum/big2str.c	(revision 42762)
@@ -32,9 +32,23 @@ big2str_poweroftwo(VALUE x, VALUE vbase) https://github.com/ruby/ruby/blob/trunk/ext/-test-/bignum/big2str.c#L32
     return rb_big2str_poweroftwo(big(x), NUM2INT(vbase));
 }
 
+#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
+static VALUE
+big2str_gmp(VALUE x, VALUE vbase)
+{
+    int base = NUM2INT(vbase);
+    if (base < 2 || 36 < base)
+        rb_raise(rb_eArgError, "invalid radix %d", base);
+    return rb_big2str_gmp(big(x), NUM2INT(vbase));
+}
+#else
+#define mul_gmp rb_f_notimplement
+#endif
+
 void
 Init_big2str(VALUE klass)
 {
     rb_define_method(rb_cInteger, "big2str_generic", big2str_generic, 1);
     rb_define_method(rb_cInteger, "big2str_poweroftwo", big2str_poweroftwo, 1);
+    rb_define_method(rb_cInteger, "big2str_gmp", big2str_gmp, 1);
 }
Index: internal.h
===================================================================
--- internal.h	(revision 42761)
+++ internal.h	(revision 42762)
@@ -644,12 +644,13 @@ VALUE rb_big_mul_normal(VALUE x, VALUE y https://github.com/ruby/ruby/blob/trunk/internal.h#L644
 VALUE rb_big_mul_balance(VALUE x, VALUE y);
 VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
 VALUE rb_big_mul_toom3(VALUE x, VALUE y);
-#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
-VALUE rb_big_mul_gmp(VALUE x, VALUE y);
-#endif
 VALUE rb_big_sq_fast(VALUE x);
 VALUE rb_big2str_poweroftwo(VALUE x, int base);
 VALUE rb_big2str_generic(VALUE x, int base);
+#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
+VALUE rb_big_mul_gmp(VALUE x, VALUE y);
+VALUE rb_big2str_gmp(VALUE x, int base);
+#endif
 
 /* file.c */
 #ifdef __APPLE__
Index: bignum.c
===================================================================
--- bignum.c	(revision 42761)
+++ bignum.c	(revision 42762)
@@ -135,6 +135,8 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdi https://github.com/ruby/ruby/blob/trunk/bignum.c#L135
 #define KARATSUBA_MUL_DIGITS 70
 #define TOOM3_MUL_DIGITS 150
 
+#define GMP_BIG2STR_DIGITS 20
+
 typedef void (mulfunc_t)(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn);
 
 static mulfunc_t bary_mul_toom3_start;
@@ -4466,6 +4468,50 @@ rb_big2str_generic(VALUE x, int base) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4468
     return big2str_generic(x, base, xds, xn);
 }
 
+#ifdef USE_GMP
+VALUE
+big2str_gmp(int negative_p, int base, BDIGIT *xds, size_t xn)
+{
+    const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGITS)*CHAR_BIT;
+    mpz_t x;
+    size_t size;
+    VALUE str;
+    char *p;
+
+    mpz_init(x);
+    mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+
+    size = mpz_sizeinbase(x, base);
+
+    if (negative_p) {
+        str = rb_usascii_str_new(0, size+1);
+        p = RSTRING_PTR(str);
+        *p++ = '-';
+    }
+    else {
+        str = rb_usascii_str_new(0, size);
+        p = RSTRING_PTR(str);
+    }
+    mpz_get_str(p, base, x);
+    mpz_clear(x);
+
+    if (RSTRING_PTR(str)[RSTRING_LEN(str)-1] == '\0') {
+        rb_str_set_len(str, RSTRING_LEN(str)-1);
+    }
+
+    return str;
+}
+
+VALUE
+rb_big2str_gmp(VALUE x, int base)
+{
+    VALUE str;
+    str = big2str_gmp(RBIGNUM_NEGATIVE_P(x), base, BDIGITS(x), RBIGNUM_LEN(x));
+    RB_GC_GUARD(x);
+    return str;
+}
+#endif
+
 static VALUE
 rb_big2str1(VALUE x, int base)
 {
@@ -4496,6 +4542,15 @@ rb_big2str1(VALUE x, int base) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4542
         return big2str_base_poweroftwo(x, base);
     }
 
+#ifdef USE_GMP
+    if (GMP_BIG2STR_DIGITS < xn) {
+        VALUE str;
+        str = big2str_gmp(RBIGNUM_NEGATIVE_P(x), base, xds, xn);
+        RB_GC_GUARD(x);
+        return str;
+    }
+#endif
+
     return big2str_generic(x, base, xds, xn);
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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