mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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:
parent
0e02d92371
commit
a77ae1eced
1 changed files with 25 additions and 23 deletions
48
bignum.c
48
bignum.c
|
@ -6291,12 +6291,11 @@ big_shift(VALUE x, long n)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
big_fdiv(VALUE x, VALUE y)
|
||||
big_fdiv(VALUE x, VALUE y, long ey)
|
||||
{
|
||||
#define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
|
||||
VALUE z;
|
||||
long l, ex, ey;
|
||||
int i;
|
||||
long l, ex;
|
||||
|
||||
bigtrunc(x);
|
||||
l = RBIGNUM_LEN(x);
|
||||
|
@ -6304,23 +6303,6 @@ big_fdiv(VALUE x, VALUE y)
|
|||
ex -= 2 * DBL_BIGDIG * BITSPERDIG;
|
||||
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);
|
||||
l = ex - ey;
|
||||
#if SIZEOF_LONG > SIZEOF_INT
|
||||
|
@ -6333,6 +6315,26 @@ big_fdiv(VALUE x, VALUE y)
|
|||
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:
|
||||
* big.fdiv(numeric) -> float
|
||||
|
@ -6356,13 +6358,13 @@ rb_big_fdiv(VALUE x, VALUE y)
|
|||
case T_FIXNUM:
|
||||
dy = (double)FIX2LONG(y);
|
||||
if (isinf(dx))
|
||||
return big_fdiv(x, y);
|
||||
return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
|
||||
break;
|
||||
|
||||
case T_BIGNUM:
|
||||
dy = rb_big2dbl(y);
|
||||
if (isinf(dx) || isinf(dy))
|
||||
return big_fdiv(x, y);
|
||||
return big_fdiv_int(x, y);
|
||||
break;
|
||||
|
||||
case T_FLOAT:
|
||||
|
@ -6370,7 +6372,7 @@ rb_big_fdiv(VALUE x, VALUE y)
|
|||
if (isnan(dy))
|
||||
return y;
|
||||
if (isinf(dx))
|
||||
return big_fdiv(x, y);
|
||||
return big_fdiv_float(x, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue