bignum.c: split rb_big_fdiv and big_fdiv

* bignum.c (rb_big_fdiv): split with big_fdiv by divider type.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42872 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-09-07 19:04:15 +00:00
parent 0e02d92371
commit a77ae1eced

View File

@ -6291,12 +6291,11 @@ big_shift(VALUE x, long n)
} }
static VALUE static VALUE
big_fdiv(VALUE x, VALUE y) big_fdiv(VALUE x, VALUE y, long ey)
{ {
#define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG) #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
VALUE z; VALUE z;
long l, ex, ey; long l, ex;
int i;
bigtrunc(x); bigtrunc(x);
l = RBIGNUM_LEN(x); l = RBIGNUM_LEN(x);
@ -6304,23 +6303,6 @@ big_fdiv(VALUE x, VALUE y)
ex -= 2 * DBL_BIGDIG * BITSPERDIG; ex -= 2 * DBL_BIGDIG * BITSPERDIG;
if (ex) x = big_shift(x, ex); if (ex) x = big_shift(x, ex);
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
case T_BIGNUM:
bigtrunc(y);
l = RBIGNUM_LEN(y);
ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
ey -= DBL_BIGDIG * BITSPERDIG;
if (ey) y = big_shift(y, ey);
break;
case T_FLOAT:
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
ey = i - DBL_MANT_DIG;
break;
default:
rb_bug("big_fdiv");
}
bigdivrem(x, y, &z, 0); bigdivrem(x, y, &z, 0);
l = ex - ey; l = ex - ey;
#if SIZEOF_LONG > SIZEOF_INT #if SIZEOF_LONG > SIZEOF_INT
@ -6333,6 +6315,26 @@ big_fdiv(VALUE x, VALUE y)
return DBL2NUM(ldexp(big2dbl(z), (int)l)); return DBL2NUM(ldexp(big2dbl(z), (int)l));
} }
static VALUE
big_fdiv_int(VALUE x, VALUE y)
{
long l, ey;
bigtrunc(y);
l = RBIGNUM_LEN(y);
ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
ey -= DBL_BIGDIG * BITSPERDIG;
if (ey) y = big_shift(y, ey);
return big_fdiv(x, y, ey);
}
static VALUE
big_fdiv_float(VALUE x, VALUE y)
{
int i;
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
return big_fdiv(x, y, i - DBL_MANT_DIG);
}
/* /*
* call-seq: * call-seq:
* big.fdiv(numeric) -> float * big.fdiv(numeric) -> float
@ -6356,13 +6358,13 @@ rb_big_fdiv(VALUE x, VALUE y)
case T_FIXNUM: case T_FIXNUM:
dy = (double)FIX2LONG(y); dy = (double)FIX2LONG(y);
if (isinf(dx)) if (isinf(dx))
return big_fdiv(x, y); return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
break; break;
case T_BIGNUM: case T_BIGNUM:
dy = rb_big2dbl(y); dy = rb_big2dbl(y);
if (isinf(dx) || isinf(dy)) if (isinf(dx) || isinf(dy))
return big_fdiv(x, y); return big_fdiv_int(x, y);
break; break;
case T_FLOAT: case T_FLOAT:
@ -6370,7 +6372,7 @@ rb_big_fdiv(VALUE x, VALUE y)
if (isnan(dy)) if (isnan(dy))
return y; return y;
if (isinf(dx)) if (isinf(dx))
return big_fdiv(x, y); return big_fdiv_float(x, y);
break; break;
default: default: