From: Tadayoshi Funaba Date: 2008-04-06T20:50:46+09:00 Subject: [ruby-dev:34263] Re: [ruby-cvs:23106] Re: Ruby:r15866 (trunk): * numeric.c (num_quo): should convert its operand to Rational. > > > * numeric.c (num_quo): should convert its operand to Rational. > > > > > > * rational.c (string_to_r_strict): should raise TypeError. > > > > > > * bignum.c (Init_Bignum): should not redefine Bignum#div. > > > Numeric#div will do. [ruby-dev:34066] このあたりの一連の修正で、mathn した場合に、1/3 などが動かなくなってい ます。とりあえず、以前のコードを元に無理やり直してみました。 Index: numeric.c =================================================================== --- numeric.c (revision 15907) +++ numeric.c (working copy) @@ -248,38 +248,19 @@ /* * call-seq: + * num.quo(numeric) => result * num.fdiv(numeric) => result * - * Performs floating point division. + * Equivalent to Numeric#/, but overridden in subclasses. */ static VALUE -num_fdiv(VALUE x, VALUE 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 - * is either rational or float (if any of operands are float). - * - * - * 654321.quo(13731) #=> Rational(218107, 4577) - * 654321.quo(13731.24) #=> 47.6519964693647 - * - */ - -static VALUE num_quo(VALUE x, VALUE y) { - return rb_funcall(rb_Rational1(x), rb_intern("quo"), 1, y); + return rb_funcall(x, '/', 1, y); } + static VALUE num_floor(VALUE num); /* @@ -294,7 +275,7 @@ static VALUE num_div(VALUE x, VALUE y) { - return rb_funcall(rb_funcall(x, '/', 1, y), rb_intern("floor"), 0, 0); + return num_floor(rb_funcall(x, '/', 1, y)); } @@ -666,7 +647,7 @@ } static VALUE -flo_fdiv(VALUE x, VALUE y) +flo_quo(VALUE x, VALUE y) { return rb_funcall(x, '/', 1, y); } @@ -2234,13 +2215,24 @@ /* * call-seq: - * fix.fdiv(numeric) => float + * 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 + * */ 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)) { @@ -3164,8 +3156,8 @@ 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, "fdiv", num_fdiv, 1); rb_define_method(rb_cNumeric, "quo", num_quo, 1); + rb_define_method(rb_cNumeric, "fdiv", num_quo, 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); @@ -3231,6 +3223,7 @@ 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); @@ -3286,7 +3279,8 @@ 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, "fdiv", flo_fdiv, 1); + rb_define_method(rb_cFloat, "quo", flo_quo, 1); + rb_define_method(rb_cFloat, "fdiv", flo_quo, 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: bignum.c =================================================================== --- bignum.c (revision 15907) +++ bignum.c (working copy) @@ -1814,6 +1814,30 @@ return bignorm(z); } +VALUE +rb_big_idiv(VALUE x, VALUE y) +{ + VALUE z; + + switch (TYPE(y)) { + case T_FIXNUM: + y = rb_int2big(FIX2LONG(y)); + break; + + case T_BIGNUM: + break; + + case T_FLOAT: + return DOUBLE2NUM(rb_big2dbl(x) / RFLOAT_VALUE(y)); + + default: + return rb_num_coerce_bin(x, y, rb_intern("div")); + } + bigdivmod(x, y, &z, 0); + + return bignorm(z); +} + /* * call-seq: * big % other => Numeric @@ -2646,6 +2670,7 @@ rb_define_method(rb_cBignum, "*", rb_big_mul, 1); rb_define_method(rb_cBignum, "/", rb_big_div, 1); rb_define_method(rb_cBignum, "%", rb_big_modulo, 1); + rb_define_method(rb_cBignum, "div", rb_big_idiv, 1); 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);