aboutsummaryrefslogtreecommitdiffstats
path: root/bignum.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-07 19:04:15 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-07 19:04:15 +0000
commita77ae1eced469384d8d17047c7fa15e64675de07 (patch)
tree82966e3b0184e659689096913c824c8b1074ffe3 /bignum.c
parent0e02d92371b3c3f1474195f1bfe7233b790be040 (diff)
downloadruby-a77ae1eced469384d8d17047c7fa15e64675de07.tar.gz
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
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/bignum.c b/bignum.c
index b7a09ae146..438bd80166 100644
--- a/bignum.c
+++ b/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: