1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* bignum.c (rb_big_fdiv): checks whether the given second argument

can be converted to float properly.

	* numeric.c (fix_fdiv): calls rb_big_fdiv when the given second
	  argument is a bignum.

	* rational.c (nurat_fdiv): should calculate Float(x/y), not
	  Float(x)/Float(y).



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tadf 2009-06-17 12:55:16 +00:00
parent bbd2b5e9bd
commit b6849b2502
5 changed files with 91 additions and 47 deletions

View file

@ -1,3 +1,14 @@
Wed Jun 17 21:25:54 2009 Tadayoshi Funaba <tadf@dotrb.org>
* bignum.c (rb_big_fdiv): checks whether the given second argument
can be converted to float properly.
* numeric.c (fix_fdiv): calls rb_big_fdiv when the given second
argument is a bignum.
* rational.c (nurat_fdiv): should calculate Float(x/y), not
Float(x)/Float(y).
Wed Jun 17 16:57:40 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
* load.c (rb_f_require): RDoc updated. a patch from Run Paint Run

View file

@ -2385,25 +2385,9 @@ big_shift(VALUE x, long n)
return x;
}
/*
* call-seq:
* big.fdiv(numeric) -> float
*
* Returns the floating point result of dividing <i>big</i> by
* <i>numeric</i>.
*
* -1234567890987654321.fdiv(13731) #=> -89910996357705.5
* -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
*
*/
static VALUE
rb_big_fdiv(VALUE x, VALUE y)
big_fdiv(VALUE x, VALUE y)
{
double dx = big2dbl(x);
double dy;
if (isinf(dx)) {
#define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
VALUE z;
long l, ex, ey;
@ -2439,23 +2423,52 @@ rb_big_fdiv(VALUE x, VALUE y)
return DBL2NUM(ldexp(big2dbl(z), (int)l));
}
case T_FLOAT:
if (isnan(RFLOAT_VALUE(y))) return y;
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
ey = i - DBL_MANT_DIG;
goto bignum;
}
}
rb_bug("big_fdiv");
/* NOTREACHED */
}
/*
* call-seq:
* big.fdiv(numeric) -> float
*
* Returns the floating point result of dividing <i>big</i> by
* <i>numeric</i>.
*
* -1234567890987654321.fdiv(13731) #=> -89910996357705.5
* -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
*
*/
VALUE
rb_big_fdiv(VALUE x, VALUE y)
{
double dx, dy;
dx = big2dbl(x);
switch (TYPE(y)) {
case T_FIXNUM:
dy = (double)FIX2LONG(y);
if (isinf(dx))
return big_fdiv(x, y);
break;
case T_BIGNUM:
dy = rb_big2dbl(y);
if (isinf(dx) || isinf(dy))
return big_fdiv(x, y);
break;
case T_FLOAT:
dy = RFLOAT_VALUE(y);
if (isnan(dy))
return y;
if (isinf(dx))
return big_fdiv(x, y);
break;
default:

View file

@ -2269,6 +2269,8 @@ fixdivmod(long x, long y, long *divp, long *modp)
*
*/
VALUE rb_big_fdiv(VALUE x, VALUE y);
static VALUE
fix_fdiv(VALUE x, VALUE y)
{
@ -2277,7 +2279,7 @@ fix_fdiv(VALUE x, VALUE y)
}
switch (TYPE(y)) {
case T_BIGNUM:
return DBL2NUM((double)FIX2LONG(x) / rb_big2dbl(y));
return rb_big_fdiv(rb_int2big(FIX2LONG(x)), y);
case T_FLOAT:
return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y));
default:

View file

@ -769,7 +769,7 @@ nurat_div(VALUE self, VALUE other)
static VALUE
nurat_fdiv(VALUE self, VALUE other)
{
return f_div(f_to_f(self), other);
return f_to_f(f_div(self, other));
}
static VALUE

View file

@ -4,6 +4,9 @@ class TestBignum < Test::Unit::TestCase
def setup
@verbose = $VERBOSE
$VERBOSE = nil
@fmax = Float::MAX.to_i
@fmax2 = @fmax * 2
@big = (1 << 63) - 1
end
def teardown
@ -395,4 +398,19 @@ class TestBignum < Test::Unit::TestCase
e = assert_raise(RangeError) {(1 << big).to_s}
assert_match(/too big to convert/, e.message)
end
def test_fix_fdiv
assert_not_equal(0, 1.fdiv(@fmax2))
assert_in_delta(0.5, 1.fdiv(@fmax2) * @fmax, 0.01)
end
def test_big_fdiv
assert_equal(1, @big.fdiv(@big))
assert_not_equal(0, @big.fdiv(@fmax2))
assert_not_equal(0, @fmax2.fdiv(@big))
assert_not_equal(0, @fmax2.fdiv(@fmax2))
assert_in_delta(0.5, @fmax.fdiv(@fmax2), 0.01)
assert_in_delta(1.0, @fmax2.fdiv(@fmax2), 0.01)
end
end