From fa161103263f001ba009cecfbc25ed336757ede7 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 7 May 2008 04:14:57 +0000 Subject: [PATCH] * 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 --- ChangeLog | 14 ++++++++++++++ bignum.c | 17 +++++------------ numeric.c | 17 ++++------------- rational.c | 40 ++++++++++++++++++--------------------- test/ruby/test_bignum.rb | 4 ++-- test/ruby/test_numeric.rb | 11 +---------- 6 files changed, 44 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0662f1c2a1..8bf04ce1ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Wed May 7 13:02:56 2008 Yukihiro Matsumoto + + * 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 * ext/zlib/zlib.c (gzreader_gets): may cause infinite loop. diff --git a/bignum.c b/bignum.c index cf375a5288..b95e51eb6a 100644 --- a/bignum.c +++ b/bignum.c @@ -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 big by * numeric. * - * -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); diff --git a/numeric.c b/numeric.c index 0ae4bb0827..cc2f3f2059 100644 --- a/numeric.c +++ b/numeric.c @@ -249,15 +249,14 @@ num_uminus(VALUE num) /* * call-seq: * num.quo(numeric) => result - * num.fdiv(numeric) => result * - * Equivalent to Numeric#/, 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 fix by * numeric. * - * 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); diff --git a/rational.c b/rational.c index a81ffe1611..f54cb70e24 100644 --- a/rational.c +++ b/rational.c @@ -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"))); diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb index 7d8409a449..d2d6f1f2cf 100644 --- a/test/ruby/test_bignum.rb +++ b/test/ruby/test_bignum.rb @@ -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 diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 8f478bd2c6..584139a7f8 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -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