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/