mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (rb_cstr_to_inum): Use BDIGIT_DBL to collect adjacent digits.
(BDIGIT_DBL_MAX): New macro. (maxpow_in_bdigit_dbl): New function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41747 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9487404c62
commit
2ade221827
2 changed files with 42 additions and 15 deletions
|
@ -1,3 +1,9 @@
|
|||
Tue Jul 2 20:25:04 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* bignum.c (rb_cstr_to_inum): Use BDIGIT_DBL to collect adjacent digits.
|
||||
(BDIGIT_DBL_MAX): New macro.
|
||||
(maxpow_in_bdigit_dbl): New function.
|
||||
|
||||
Tue Jul 2 17:23:33 2013 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* doc/syntax/refinements.rdoc: add description of Module#using and
|
||||
|
|
51
bignum.c
51
bignum.c
|
@ -61,6 +61,7 @@ static VALUE big_three = Qnil;
|
|||
#define BIGDN(x) RSHIFT((x),BITSPERDIG)
|
||||
#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
|
||||
#define BDIGMAX ((BDIGIT)(BIGRAD-1))
|
||||
#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
|
||||
|
||||
#if SIZEOF_BDIGITS == 2
|
||||
# define swap_bdigit(x) swap16(x)
|
||||
|
@ -220,6 +221,23 @@ static int nlz(BDIGIT x) { return nlz128((uint128_t)x); }
|
|||
32 - nlz32(x))
|
||||
#endif
|
||||
|
||||
static BDIGIT_DBL
|
||||
maxpow_in_bdigit_dbl(int base, int *exp_ret)
|
||||
{
|
||||
BDIGIT_DBL maxpow;
|
||||
int exponent;
|
||||
|
||||
maxpow = base;
|
||||
exponent = 1;
|
||||
while (maxpow <= BDIGIT_DBL_MAX / base) {
|
||||
maxpow *= base;
|
||||
exponent++;
|
||||
}
|
||||
|
||||
*exp_ret = exponent;
|
||||
return maxpow;
|
||||
}
|
||||
|
||||
static int
|
||||
bary_zero_p(BDIGIT *xds, size_t nx)
|
||||
{
|
||||
|
@ -2071,31 +2089,33 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
|
|||
}
|
||||
}
|
||||
else {
|
||||
BDIGIT hbase;
|
||||
VALUE hbasev;
|
||||
int hbase_numdigits;
|
||||
int digits_per_bdigits_dbl;
|
||||
BDIGIT_DBL power;
|
||||
VALUE powerv;
|
||||
int j;
|
||||
size_t num_bdigits;
|
||||
size_t unit;
|
||||
VALUE tmpu = 0, tmpv = 0;
|
||||
BDIGIT *uds, *vds, *tds;
|
||||
calc_hbase(base, &hbase, &hbase_numdigits);
|
||||
|
||||
power = maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
|
||||
|
||||
size = p - buf;
|
||||
num_bdigits = roomof(size, hbase_numdigits);
|
||||
num_bdigits = roomof(size, digits_per_bdigits_dbl)*2;
|
||||
|
||||
uds = ALLOCV_N(BDIGIT, tmpu, num_bdigits);
|
||||
vds = ALLOCV_N(BDIGIT, tmpv, num_bdigits);
|
||||
|
||||
hbasev = bignew(1, 1);
|
||||
BDIGITS(hbasev)[0] = hbase;
|
||||
powerv = bignew(2, 1);
|
||||
BDIGITS(powerv)[0] = BIGLO(power);
|
||||
BDIGITS(powerv)[1] = BIGDN(power);
|
||||
|
||||
i = 0;
|
||||
while (buf < p) {
|
||||
int m;
|
||||
BDIGIT d = 0;
|
||||
if (hbase_numdigits <= p - buf) {
|
||||
m = hbase_numdigits;
|
||||
BDIGIT_DBL d = 0;
|
||||
if (digits_per_bdigits_dbl <= p - buf) {
|
||||
m = digits_per_bdigits_dbl;
|
||||
}
|
||||
else {
|
||||
m = (int)(p - buf);
|
||||
|
@ -2104,23 +2124,24 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
|
|||
for (j = 0; j < m; j++) {
|
||||
d = d * base + p[j];
|
||||
}
|
||||
uds[i++] = d;
|
||||
uds[i++] = BIGLO(d);
|
||||
uds[i++] = BIGDN(d);
|
||||
}
|
||||
for (unit = 1; unit < num_bdigits; unit *= 2) {
|
||||
for (unit = 2; unit < num_bdigits; unit *= 2) {
|
||||
for (i = 0; i < num_bdigits; i += unit*2) {
|
||||
if (2*unit <= num_bdigits - i) {
|
||||
bary_mul2(vds+i, unit*2, BDIGITS(hbasev), RBIGNUM_LEN(hbasev), uds+i+unit, unit);
|
||||
bary_mul2(vds+i, unit*2, BDIGITS(powerv), RBIGNUM_LEN(powerv), uds+i+unit, unit);
|
||||
bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
|
||||
}
|
||||
else if (unit <= num_bdigits - i) {
|
||||
bary_mul2(vds+i, num_bdigits-i, BDIGITS(hbasev), RBIGNUM_LEN(hbasev), uds+i+unit, num_bdigits-(i+unit));
|
||||
bary_mul2(vds+i, num_bdigits-i, BDIGITS(powerv), RBIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
|
||||
bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
|
||||
}
|
||||
else {
|
||||
MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
|
||||
}
|
||||
}
|
||||
hbasev = bigtrunc(bigmul0(hbasev, hbasev));
|
||||
powerv = bigtrunc(bigmul0(powerv, powerv));
|
||||
tds = vds;
|
||||
vds = uds;
|
||||
uds = tds;
|
||||
|
|
Loading…
Reference in a new issue