diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-01 14:34:53 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-01 14:34:53 +0000 |
commit | b64c2c348f05784cb3dad92c97093baf3e93885f (patch) | |
tree | fbd057fa4f4d160c2d605bfa471c49497f2ff11f /bignum.c | |
parent | 4dd7a13a0a00d66592049e1f9a79a9cfddf11a07 (diff) |
* 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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42762 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -135,6 +135,8 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0); #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) 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) 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); } |