ruby-changes:4396
From: ko1@a...
Date: Wed, 2 Apr 2008 23:14:15 +0900 (JST)
Subject: [ruby-changes:4396] matz - Ruby:r15887 (trunk): * numeric.c (num_rdiv): should always return rational number.
matz 2008-04-02 23:13:53 +0900 (Wed, 02 Apr 2008) New Revision: 15887 Modified files: trunk/.gdbinit trunk/ChangeLog trunk/numeric.c trunk/rational.c trunk/test/ruby/test_bignum.rb trunk/test/ruby/test_numeric.rb trunk/test/ruby/test_rational.rb Log: * numeric.c (num_rdiv): should always return rational number. * rational.c (nurat_add, nurat_sub, nurat_mul, nurat_fdiv, nurat_cmp): use rb_num_coerce_bin(). * rational.c (nurat_division): does / and rdiv. * .gdbinit (rp): no longer use rb_p(). http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/numeric.c?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_bignum.rb?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/.gdbinit?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_rational.rb?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_numeric.rb?r1=15887&r2=15886&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/rational.c?r1=15887&r2=15886&diff_format=u Index: .gdbinit =================================================================== --- .gdbinit (revision 15886) +++ .gdbinit (revision 15887) @@ -145,11 +145,11 @@ else if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL printf "T_RATIONAL: " - rb_p $arg0 + print (struct RRational *)$arg0 else if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX printf "T_COMPLEX: " - rb_p $arg0 + print (struct RComplex *)$arg0 else if ($flags & RUBY_T_MASK) == RUBY_T_FILE printf "T_FILE: " Index: ChangeLog =================================================================== --- ChangeLog (revision 15886) +++ ChangeLog (revision 15887) @@ -2,6 +2,15 @@ * rational.c (nurat_int_check): function for DRY integer check. + * numeric.c (num_rdiv): should always return rational number. + + * rational.c (nurat_add, nurat_sub, nurat_mul, nurat_fdiv, + nurat_cmp): use rb_num_coerce_bin(). + + * rational.c (nurat_division): does / and rdiv. + + * .gdbinit (rp): no longer use rb_p(). + Wed Apr 2 06:52:31 2008 Yukihiro Matsumoto <matz@r...> * .gdbinit (rp): supports rational and complex numbers. it's Index: numeric.c =================================================================== --- numeric.c (revision 15886) +++ numeric.c (revision 15887) @@ -248,19 +248,47 @@ /* * call-seq: - * num.quo(numeric) => result * num.fdiv(numeric) => result * - * Equivalent to <code>Numeric#/</code>, but overridden in subclasses. + * Performs floating point division. */ static VALUE -num_quo(VALUE x, VALUE y) +num_fdiv(VALUE x, VALUE y) { - return rb_funcall(x, '/', 1, rb_Rational1(y)); + return rb_funcall(rb_Float(x), '/', 1, y); } +/* + * Document-method: quo + * + * call-seq: + * num.quo(numeric) => result + * + * Suppose to return most accurate division result, which + * by default in ratinal number for 1.9. + * + */ +/* + * Document-method: rdiv + * + * call-seq: + * num.rdiv(numeric) => result + * + * Performs rational number division. + * + * 654321.rdiv(13731) #=> Rational(218107, 4577) + * 654321.rdiv(13731.5) #=> Rational(1308642, 27463) + * + */ + +static VALUE +num_rdiv(VALUE x, VALUE y) +{ + return rb_funcall(rb_Rational1(x), rb_intern("rdiv"), 1, y); +} + static VALUE num_floor(VALUE num); /* @@ -647,17 +675,11 @@ } static VALUE -flo_quo(VALUE x, VALUE y) +flo_fdiv(VALUE x, VALUE y) { return rb_funcall(x, '/', 1, y); } -static VALUE -flo_rdiv(VALUE x, VALUE y) -{ - return rb_funcall(rb_Rational1(x), '/', 1, y); -} - static void flodivmod(double x, double y, double *divp, double *modp) { @@ -2221,24 +2243,17 @@ /* * call-seq: - * fix.quo(numeric) => float - * fix.fdiv(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.rdiv(13731) #=> Rational(218107, 4577) + * 654321.rdiv(13731.24) #=> Rational(1308642, 27463) * */ 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) { if (FIXNUM_P(y)) { @@ -3162,9 +3177,9 @@ rb_define_method(rb_cNumeric, "-@", num_uminus, 0); rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); rb_define_method(rb_cNumeric, "eql?", num_eql, 1); - rb_define_method(rb_cNumeric, "quo", num_quo, 1); - rb_define_method(rb_cNumeric, "rdiv", num_quo, 1); - rb_define_method(rb_cNumeric, "fdiv", num_quo, 1); + rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); + rb_define_method(rb_cNumeric, "quo", num_rdiv, 1); + rb_define_method(rb_cNumeric, "rdiv", num_rdiv, 1); rb_define_method(rb_cNumeric, "div", num_div, 1); rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); rb_define_method(rb_cNumeric, "modulo", num_modulo, 1); @@ -3230,8 +3245,6 @@ 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, "rdiv", fix_quo, 1); rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1); rb_define_method(rb_cFixnum, "**", fix_pow, 1); @@ -3287,9 +3300,7 @@ rb_define_method(rb_cFloat, "-", flo_minus, 1); rb_define_method(rb_cFloat, "*", flo_mul, 1); rb_define_method(rb_cFloat, "/", flo_div, 1); - rb_define_method(rb_cFloat, "quo", flo_quo, 1); - rb_define_method(rb_cFloat, "rdiv", flo_rdiv, 1); - rb_define_method(rb_cFloat, "fdiv", flo_quo, 1); + rb_define_method(rb_cFloat, "fdiv", flo_fdiv, 1); rb_define_method(rb_cFloat, "%", flo_mod, 1); rb_define_method(rb_cFloat, "modulo", flo_mod, 1); rb_define_method(rb_cFloat, "divmod", flo_divmod, 1); Index: test/ruby/test_bignum.rb =================================================================== --- test/ruby/test_bignum.rb (revision 15886) +++ test/ruby/test_bignum.rb (revision 15887) @@ -262,7 +262,7 @@ assert_equal(T32.to_f, T32.quo(1.0)) assert_equal(T32.to_f, T32.quo(T_ONE)) - assert_raise(TypeError) { T32.quo("foo") } + assert_raise(ArgumentError) { T32.quo("foo") } assert_equal(1024**1024, (1024**1024).quo(1)) assert_equal(1024**1024, (1024**1024).quo(1.0)) Index: test/ruby/test_numeric.rb =================================================================== --- test/ruby/test_numeric.rb (revision 15886) +++ test/ruby/test_numeric.rb (revision 15887) @@ -51,16 +51,7 @@ 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(0)} end def test_divmod Index: test/ruby/test_rational.rb =================================================================== --- test/ruby/test_rational.rb (revision 15886) +++ test/ruby/test_rational.rb (revision 15887) @@ -943,7 +943,7 @@ assert_equal(Rational(1,2), 1.quo(2)) assert_equal(Rational(5000000000), 10000000000.quo(2)) - assert_equal(0.5, 1.0.quo(2)) + assert_equal(Rational(1,2), 1.0.quo(2)) assert_equal(Rational(1,4), Rational(1,2).quo(2)) assert_equal(Rational(1,2), 1.rdiv(2)) Index: rational.c =================================================================== --- rational.c (revision 15886) +++ rational.c (revision 15887) @@ -22,7 +22,7 @@ VALUE rb_cRational; -static ID id_Unify, id_abs, id_cmp, id_coerce, id_convert, id_equal_p, +static ID id_Unify, id_abs, id_cmp, id_convert, id_equal_p, id_expt, id_floor, id_format,id_idiv, id_inspect, id_negate, id_new, id_new_bang, id_to_f, id_to_i, id_to_s, id_truncate; @@ -175,8 +175,6 @@ fun1(to_s) fun1(truncate) -fun2(coerce) - inline static VALUE f_equal_p(VALUE x, VALUE y) { @@ -681,10 +679,7 @@ bdat->num, bdat->den, '+'); } default: - { - VALUE a = f_coerce(other, self); - return f_add(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, '+'); } } @@ -712,10 +707,7 @@ bdat->num, bdat->den, '-'); } default: - { - VALUE a = f_coerce(other, self); - return f_sub(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, '-'); } } @@ -781,16 +773,17 @@ bdat->num, bdat->den, '*'); } default: - { - VALUE a = f_coerce(other, self); - return f_mul(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, '*'); } } +#define id_to_r rb_intern("to_r") +#define f_to_r(x) rb_funcall(x, id_to_r, 0) + static VALUE -nurat_div(VALUE self, VALUE other) +nurat_division(VALUE self, VALUE other, int rdiv) { + again: switch (TYPE(other)) { case T_FIXNUM: case T_BIGNUM: @@ -804,7 +797,11 @@ other, ONE, '/'); } case T_FLOAT: - return f_div(f_to_f(self), other); + if (rdiv) { + other = f_to_r(other); + goto again; + } + return rb_funcall(f_to_f(self), '/', 1, other); case T_RATIONAL: if (f_zero_p(other)) rb_raise(rb_eZeroDivError, "devided by zero"); @@ -816,14 +813,23 @@ bdat->num, bdat->den, '/'); } default: - { - VALUE a = f_coerce(other, self); - return f_div(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, '/'); } } static VALUE +nurat_div(VALUE self, VALUE other) +{ + return nurat_division(self, other, Qfalse); +} + +static VALUE +nurat_rdiv(VALUE self, VALUE other) +{ + return nurat_division(self, other, Qtrue); +} + +static VALUE nurat_fdiv(VALUE self, VALUE other) { return f_div(f_to_f(self), other); @@ -874,10 +880,7 @@ case T_RATIONAL: return f_expt(f_to_f(self), other); default: - { - VALUE a = f_coerce(other, self); - return f_expt(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, rb_intern("**")); } } @@ -914,10 +917,7 @@ return f_cmp(f_sub(num1, num2), ZERO); } default: - { - VALUE a = f_coerce(other, self); - return f_cmp(RARRAY_PTR(a)[0], RARRAY_PTR(a)[1]); - } + return rb_num_coerce_bin(self, other, rb_intern("<=>")); } } @@ -1423,9 +1423,6 @@ return rb_rational_new1(INT2FIX(0)); } -#define id_to_r rb_intern("to_r") -#define f_to_r(x) rb_funcall(x, id_to_r, 0) - static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass) { @@ -1514,7 +1511,6 @@ id_Unify = rb_intern("Unify"); id_abs = rb_intern("abs"); id_cmp = rb_intern("<=>"); - id_coerce = rb_intern("coerce"); id_convert = rb_intern("convert"); id_equal_p = rb_intern("=="); id_expt = rb_intern("**"); @@ -1553,6 +1549,8 @@ rb_define_method(rb_cRational, "-", nurat_sub, 1); rb_define_method(rb_cRational, "*", nurat_mul, 1); rb_define_method(rb_cRational, "/", nurat_div, 1); + rb_define_method(rb_cRational, "quo", nurat_rdiv, 1); + rb_define_method(rb_cRational, "rdiv", nurat_rdiv, 1); rb_define_method(rb_cRational, "fdiv", nurat_fdiv, 1); rb_define_method(rb_cRational, "**", nurat_expt, 1); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/