diff --git a/ChangeLog b/ChangeLog index d71e8ed7aa0b18..67314897928866 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Sat Jun 20 21:11:43 2009 Tadayoshi Funaba + + * numeric.c (num_div): don't use num_floor which is actually + flo_floor. + + * numeric.c (num_modulo): don't call '%'. + + * numeric.c (num_divmod): use num_modulo. + + * numeric.c: defined '%'. + + * rational.c (nurat_idiv,nurat_mod,nurat_divmod,nurat_rem): removed. + Sat Jun 20 20:28:44 2009 Tadayoshi Funaba * complex.c: edited rdoc. diff --git a/numeric.c b/numeric.c index c20e510736e1c4..8435d7f691d7f1 100644 --- a/numeric.c +++ b/numeric.c @@ -282,8 +282,6 @@ num_fdiv(VALUE x, VALUE y) } -static VALUE num_floor(VALUE num); - /* * call-seq: * num.div(numeric) => integer @@ -302,10 +300,54 @@ static VALUE num_div(VALUE x, VALUE y) { if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv(); - return num_floor(rb_funcall(x, '/', 1, y)); + return rb_funcall(rb_funcall(x, '/', 1, y), rb_intern("floor"), 0); } +/* + * call-seq: + * num.modulo(numeric) => real + * + * x.modulo(y) means x-y*(x/y).floor + * + * Equivalent to + * num.divmod(aNumeric)[1]. + * + * See Numeric#divmod. + */ + +static VALUE +num_modulo(VALUE x, VALUE y) +{ + return rb_funcall(x, '-', 1, + rb_funcall(y, '*', 1, + rb_funcall(x, rb_intern("div"), 1, y))); +} + +/* + * call-seq: + * num.remainder(numeric) => real + * + * x.remainder(y) means x-y*(x/y).truncate + * + * See Numeric#divmod. + */ + +static VALUE +num_remainder(VALUE x, VALUE y) +{ + VALUE z = rb_funcall(x, '%', 1, y); + + if ((!rb_equal(z, INT2FIX(0))) && + ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) && + RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) || + (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) && + RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) { + return rb_funcall(z, '-', 1, y); + } + return z; +} + /* * call-seq: * num.divmod(numeric) => array @@ -350,49 +392,7 @@ num_div(VALUE x, VALUE y) static VALUE num_divmod(VALUE x, VALUE y) { - return rb_assoc_new(num_div(x, y), rb_funcall(x, '%', 1, y)); -} - -/* - * call-seq: - * num.modulo(numeric) => real - * - * x.modulo(y) means x-y*(x/y).floor - * - * Equivalent to - * num.divmod(aNumeric)[1]. - * - * See Numeric#divmod. - */ - -static VALUE -num_modulo(VALUE x, VALUE y) -{ - return rb_funcall(x, '%', 1, y); -} - -/* - * call-seq: - * num.remainder(numeric) => real - * - * x.remainder(y) means x-y*(x/y).truncate - * - * See Numeric#divmod. - */ - -static VALUE -num_remainder(VALUE x, VALUE y) -{ - VALUE z = rb_funcall(x, '%', 1, y); - - if ((!rb_equal(z, INT2FIX(0))) && - ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) && - RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) || - (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) && - RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) { - return rb_funcall(z, '-', 1, y); - } - return z; + return rb_assoc_new(num_div(x, y), num_modulo(x, y)); } /* @@ -3153,6 +3153,7 @@ Init_Numeric(void) rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); rb_define_method(rb_cNumeric, "div", num_div, 1); rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); + rb_define_method(rb_cNumeric, "%", num_modulo, 1); rb_define_method(rb_cNumeric, "modulo", num_modulo, 1); rb_define_method(rb_cNumeric, "remainder", num_remainder, 1); rb_define_method(rb_cNumeric, "abs", num_abs, 0); diff --git a/rational.c b/rational.c index d76983f353d3d8..707aa8260044c3 100644 --- a/rational.c +++ b/rational.c @@ -1092,91 +1092,6 @@ nurat_coerce(VALUE self, VALUE other) return Qnil; } -/* - * call-seq: - * rat.div(numeric) => integer - * - * Uses +/+ to divide _rat_ by _numeric_, then returns the floor of the result - * as an +Integer+ object. - * - * A +TypeError+ is raised unless _numeric_ is a +Numeric+ object. A - * +ZeroDivisionError+ is raised if _numeric_ is 0. A +FloatDomainError+ is - * raised if _numeric_ is 0.0. - * - * For example: - * - * Rational(2, 3).div(Rational(2, 3)) #=> 1 - * Rational(-2, 9).div(Rational(-9, 2)) #=> 0 - * Rational(3, 4).div(0.1) #=> 7 - * Rational(-9).div(9.9) #=> -1 - * Rational(3.12).div(0.5) #=> 6 - * Rational(200, 51).div(0) #=> ZeroDivisionError: - * # divided by zero - */ -static VALUE -nurat_idiv(VALUE self, VALUE other) -{ - return f_floor(f_div(self, other)); -} - -/* - * call-seq: - * rat.modulo(numeric) => real - * rat % numeric => real - * - * Returns the modulo of _rat_ and _numeric_ as a +Numeric+ object. - * - * x.modulo(y) means x-y*(x/y).floor - * - * A +TypeError+ is raised unless _numeric_ is a +Numeric+ object. A - * +ZeroDivisionError+ is raised if _numeric_ is 0. A +FloatDomainError+ is - * raised if _numeric_ is 0.0. - * - * For example: - * - * Rational(2, 3) % Rational(2, 3) #=> (0/1) - * Rational(2) % Rational(300) #=> (2/1) - * Rational(-2, 9) % Rational(9, -2) #=> (-2/9) - * Rational(8.2) % 3.2 #=> 1.799999999999999 - * Rational(198.1) % 2.3e3 #=> 198.1 - * Rational(2, 5) % 0.0 #=> FloatDomainError: Infinity - */ -static VALUE -nurat_mod(VALUE self, VALUE other) -{ - VALUE val = f_floor(f_div(self, other)); - return f_sub(self, f_mul(other, val)); -} - -/* - * call-seq: - * rat.divmod(numeric) => array - * - * Returns a two-element +Array+ containing the quotient and modulus - * obtained by dividing _rat_ by _numeric_. The first element is - * an integer. The second selement is a real. - * - * A +ZeroDivisionError+ is raised if _numeric_ is 0. A +FloatDomainError+ is - * raised if _numeric_ is 0.0. A +TypeError+ is raised unless _numeric_ is a - * +Numeric+ object. - * - * For example: - * - * Rational(3).divmod(3) #=> [1, (0/1)] - * Rational(4).divmod(3) #=> [1, (1/1)] - * Rational(5).divmod(3) #=> [1, (2/1)] - * Rational(6).divmod(3) #=> [2, (0/1)] - * Rational(2, 3).divmod(Rational(2, 3)) #=> [1, (0/1)] - * Rational(-2, 9).divmod(Rational(9, -2)) #=> [0, (-2/9)] - * Rational(11.5).divmod(Rational(3.5)) #=> [3, (1/1)] - */ -static VALUE -nurat_divmod(VALUE self, VALUE other) -{ - VALUE val = f_floor(f_div(self, other)); - return rb_assoc_new(val, f_sub(self, f_mul(other, val))); -} - #if 0 /* :nodoc: */ static VALUE @@ -1184,37 +1099,8 @@ nurat_quot(VALUE self, VALUE other) { return f_truncate(f_div(self, other)); } -#endif -/* - * call-seq: - * rat.remainder(numeric) => real - * - * Returns the remainder of dividing _rat_ by _numeric_ as a +Numeric+ object. - * - * x.remainder(y) means x-y*(x/y).truncate - * - * A +ZeroDivisionError+ is raised if _numeric_ is 0. A +FloatDomainError+ is - * raised if the result is Infinity or NaN, or _numeric_ is 0.0. A +TypeError+ - * is raised unless _numeric_ is a +Numeric+ object. - * - * For example: - * - * Rational(3, 4).remainder(Rational(3)) #=> (3/4) - * Rational(12,13).remainder(-8) #=> (12/13) - * Rational(2,3).remainder(-Rational(3,2)) #=> (2/3) - * Rational(-5,7).remainder(7.1) #=> -0.7142857142857143 - * Rational(1).remainder(0) # ZeroDivisionError: - * # divided by zero - */ -static VALUE -nurat_rem(VALUE self, VALUE other) -{ - VALUE val = f_truncate(f_div(self, other)); - return f_sub(self, f_mul(other, val)); -} -#if 0 /* :nodoc: */ static VALUE nurat_quotrem(VALUE self, VALUE other) @@ -2241,21 +2127,12 @@ Init_Rational(void) rb_define_method(rb_cRational, "==", nurat_equal_p, 1); rb_define_method(rb_cRational, "coerce", nurat_coerce, 1); - rb_define_method(rb_cRational, "div", nurat_idiv, 1); - #if 0 /* NUBY */ rb_define_method(rb_cRational, "//", nurat_idiv, 1); #endif - rb_define_method(rb_cRational, "modulo", nurat_mod, 1); - rb_define_method(rb_cRational, "%", nurat_mod, 1); - rb_define_method(rb_cRational, "divmod", nurat_divmod, 1); - #if 0 rb_define_method(rb_cRational, "quot", nurat_quot, 1); -#endif - rb_define_method(rb_cRational, "remainder", nurat_rem, 1); -#if 0 rb_define_method(rb_cRational, "quotrem", nurat_quotrem, 1); #endif diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 0dd7b2e99cb0d4..43d53e7fcfbba4 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -55,6 +55,7 @@ def test_quo end def test_divmod +=begin DummyNumeric.class_eval do def /(x); 42.0; end def %(x); :mod; end @@ -63,13 +64,16 @@ def %(x); :mod; end assert_equal(42, DummyNumeric.new.div(1)) assert_equal(:mod, DummyNumeric.new.modulo(1)) assert_equal([42, :mod], DummyNumeric.new.divmod(1)) +=end assert_kind_of(Integer, 11.divmod(3.5).first, '[ruby-dev:34006]') +=begin ensure DummyNumeric.class_eval do remove_method :/, :% end +=end end def test_real_p