mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
4dd7a13a0a
commit
b64c2c348f
4 changed files with 83 additions and 3 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Sun Sep 1 23:30:47 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* 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@fsij.org>
|
||||
|
||||
* bignum.c (bary_mul_gmp): Use mpz_init and mpz_clear instead of
|
||||
|
|
55
bignum.c
55
bignum.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,23 @@ big2str_poweroftwo(VALUE x, VALUE vbase)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -644,12 +644,13 @@ VALUE rb_big_mul_normal(VALUE x, VALUE y);
|
|||
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__
|
||||
|
|
Loading…
Reference in a new issue