* bignum.c (rb_big_fdiv): flo.fdiv(NaN) should result NaN.

* numeric.c (num_quo): renamed and moved from bignum.c.
  [ruby-dev:34582]

* bignum.c (rb_big_fdiv): update RDoc description

* rational.c (nurat_s_new_m): small refactoring.

* bignum.c (rb_big2dbl): no need for forceful warning when
  converting to float.  overflow is a nature of float values.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16308 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2008-05-07 04:14:57 +00:00
Родитель f7b3f1c528
Коммит fa16110326
6 изменённых файлов: 44 добавлений и 59 удалений

Просмотреть файл

@ -1,3 +1,17 @@
Wed May 7 13:02:56 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
* bignum.c (rb_big_fdiv): flo.fdiv(NaN) should result NaN.
* numeric.c (num_quo): renamed and moved from bignum.c.
[ruby-dev:34582]
* bignum.c (rb_big_fdiv): update RDoc description
* rational.c (nurat_s_new_m): small refactoring.
* bignum.c (rb_big2dbl): no need for forceful warning when
converting to float. overflow is a nature of float values.
Wed May 7 00:54:25 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/zlib/zlib.c (gzreader_gets): may cause infinite loop.

Просмотреть файл

@ -1219,7 +1219,7 @@ rb_big2dbl(VALUE x)
double d = big2dbl(x);
if (isinf(d)) {
rb_warn("Bignum out of Float range");
rb_warning("Bignum out of Float range");
d = HUGE_VAL;
}
return d;
@ -1975,23 +1975,16 @@ static VALUE big_shift(VALUE x, int n)
/*
* call-seq:
* big.quo(numeric) -> float
* big.fdiv(numeric) -> float
* big.fdiv(numeric) -> float
*
* Returns the floating point result of dividing <i>big</i> by
* <i>numeric</i>.
*
* -1234567890987654321.quo(13731) #=> -89910996357705.5
* -1234567890987654321.quo(13731.24) #=> -89909424858035.7
* -1234567890987654321.fdiv(13731) #=> -89910996357705.5
* -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
*
*/
static VALUE
rb_big_quo(VALUE x, VALUE y)
{
return rb_funcall(rb_rational_raw1(x), '/', 1, rb_Rational1(y));
}
static VALUE
rb_big_fdiv(VALUE x, VALUE y)
{
@ -2021,6 +2014,7 @@ rb_big_fdiv(VALUE x, VALUE y)
return DOUBLE2NUM(ldexp(big2dbl(z), ex - ey));
}
case T_FLOAT:
if (isnan(RFLOAT_VALUE(y))) return y;
y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &ey), DBL_MANT_DIG));
ey -= DBL_MANT_DIG;
goto bignum;
@ -2688,7 +2682,6 @@ Init_Bignum(void)
rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1);
rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
rb_define_method(rb_cBignum, "quo", rb_big_quo, 1);
rb_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
rb_define_method(rb_cBignum, "&", rb_big_and, 1);

Просмотреть файл

@ -249,15 +249,14 @@ num_uminus(VALUE num)
/*
* call-seq:
* num.quo(numeric) => result
* num.fdiv(numeric) => result
*
* Equivalent to <code>Numeric#/</code>, but overridden in subclasses.
* Returns most exact division (rational for integers, float for floats).
*/
static VALUE
num_quo(VALUE x, VALUE y)
{
return rb_funcall(x, '/', 1, y);
return rb_funcall(rb_rational_raw1(x), '/', 1, y);
}
@ -2215,23 +2214,16 @@ fixdivmod(long x, long y, long *divp, long *modp)
/*
* call-seq:
* fix.quo(numeric) => float
* fix.fdiv(numeric) => float
*
* Returns the floating point result of dividing <i>fix</i> by
* <i>numeric</i>.
*
* 654321.quo(13731) #=> 47.6528293642124
* 654321.quo(13731.24) #=> 47.6519964693647
* 654321.fdiv(13731) #=> 47.6528293642124
* 654321.fdiv(13731.24) #=> 47.6519964693647
*
*/
static VALUE
fix_quo(VALUE x, VALUE y)
{
return rb_funcall(rb_rational_raw1(x), '/', 1, y);
}
static VALUE
fix_fdiv(VALUE x, VALUE y)
{
@ -3225,7 +3217,6 @@ Init_Numeric(void)
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
rb_define_method(rb_cFixnum, "quo", fix_quo, 1);
rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
rb_define_method(rb_cFixnum, "**", fix_pow, 1);

Просмотреть файл

@ -500,10 +500,8 @@ nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass)
{
VALUE num, den;
switch (rb_scan_args(argc, argv, "11", &num, &den)) {
case 1:
if (rb_scan_args(argc, argv, "11", &num, &den) == 1) {
den = ONE;
break;
}
nurat_int_check(num);
@ -514,22 +512,25 @@ nurat_s_canonicalize(int argc, VALUE *argv, VALUE klass)
#endif
static VALUE
nurat_s_new(int argc, VALUE *argv, VALUE klass)
nurat_s_new(VALUE klass, VALUE num, VALUE den)
{
VALUE num, den;
switch (rb_scan_args(argc, argv, "11", &num, &den)) {
case 1:
den = ONE;
break;
}
nurat_int_check(num);
nurat_int_check(den);
return nurat_s_canonicalize_internal(klass, num, den);
}
static VALUE
nurat_s_new_m(int argc, VALUE *argv, VALUE klass)
{
VALUE num, den;
if (rb_scan_args(argc, argv, "11", &num, &den) == 1) {
den = ONE;
}
return nurat_s_new(klass, num, den);
}
inline static VALUE
f_rational_new1(VALUE klass, VALUE x)
{
@ -1425,9 +1426,9 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
{
VALUE a1, a2;
a1 = Qnil;
a2 = Qnil;
rb_scan_args(argc, argv, "02", &a1, &a2);
if (rb_scan_args(argc, argv, "02", &a1, &a2) == 1) {
a2 = ONE;
}
switch (TYPE(a1)) {
case T_COMPLEX:
@ -1486,12 +1487,7 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
return f_div(a1, a2);
}
{
VALUE argv2[2];
argv2[0] = a1;
argv2[1] = a2;
return nurat_s_new(argc, argv2, klass);
}
return nurat_s_new(klass, a1, a2);
}
static VALUE
@ -1533,7 +1529,7 @@ Init_Rational(void)
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
ID2SYM(rb_intern("new!")));
rb_define_singleton_method(rb_cRational, "new", nurat_s_new, -1);
rb_define_singleton_method(rb_cRational, "new", nurat_s_new_m, -1);
rb_funcall(rb_cRational, rb_intern("private_class_method"), 1,
ID2SYM(rb_intern("new")));

Просмотреть файл

@ -263,14 +263,14 @@ class TestBignum < Test::Unit::TestCase
assert_equal(T32.to_f, T32.quo(1.0))
assert_equal(T32.to_f, T32.quo(T_ONE))
assert_raise(ArgumentError) { T32.quo("foo") }
assert_raise(TypeError) { T32.quo("foo") }
assert_equal(1024**1024, (1024**1024).quo(1))
assert_equal(1024**1024, (1024**1024).quo(1.0))
assert_equal(1024**1024*2, (1024**1024*2).quo(1))
inf = 1 / 0.0; nan = inf / inf
assert_raise(FloatDomainError) { (1024**1024*2).quo(nan) }
assert((1024**1024*2).quo(nan).nan?)
end
def test_pow

Просмотреть файл

@ -51,16 +51,7 @@ class TestNumeric < Test::Unit::TestCase
end
def test_quo
DummyNumeric.class_eval do
def /(x); :div; end
end
assert_equal(:div, DummyNumeric.new.quo(0))
ensure
DummyNumeric.class_eval do
remove_method :/
end
assert_raise(ArgumentError) {DummyNumeric.new.quo(1)}
end
def test_divmod