From a9ec8adff324bffa6f3cd18620b674e5737ce0bc Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 23 Jan 2003 06:22:50 +0000 Subject: [PATCH] * lib/rational.rb: modified to support "quo". * numeric.c (num_quo): should return most exact quotient value, i.e. float by default, rational if available. * numeric.c (num_div): "div" should return x.divmod(x)[0]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3399 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 +++++++++ bignum.c | 28 +++++++++++++++++++++++++++- lib/mathn.rb | 11 ++--------- lib/rational.rb | 43 ++++++------------------------------------- numeric.c | 39 +++++++++++++++++++++++---------------- 5 files changed, 67 insertions(+), 63 deletions(-) diff --git a/ChangeLog b/ChangeLog index cae1f7c322..5a5a0f26da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Jan 23 14:56:52 2003 Yukihiro Matsumoto + + * lib/rational.rb: modified to support "quo". + + * numeric.c (num_quo): should return most exact quotient value, + i.e. float by default, rational if available. + + * numeric.c (num_div): "div" should return x.divmod(x)[0]. + Thu Jan 23 13:24:18 2003 Yukihiro Matsumoto * time.c (time_arg): was accessing garbage argv value. diff --git a/bignum.c b/bignum.c index 16cb8e1602..2312474c3e 100644 --- a/bignum.c +++ b/bignum.c @@ -1284,7 +1284,6 @@ rb_big_div(x, y) return bignorm(z); } - static VALUE rb_big_modulo(x, y) VALUE x, y; @@ -1351,6 +1350,32 @@ rb_big_divmod(x, y) return rb_assoc_new(bignorm(div), bignorm(mod)); } +static VALUE +rb_big_quo(x, y) + VALUE x, y; +{ + double dx = rb_big2dbl(x); + double dy; + + switch (TYPE(y)) { + case T_FIXNUM: + dy = (double)FIX2LONG(y); + break; + + case T_BIGNUM: + dy = rb_big2dbl(y); + break; + + case T_FLOAT: + dy = RFLOAT(y)->value; + break; + + default: + return rb_num_coerce_bin(x, y); + } + return rb_float_new(dx / dy); +} + VALUE rb_big_pow(x, y) VALUE x, y; @@ -1739,6 +1764,7 @@ Init_Bignum() 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, "**", rb_big_pow, 1); rb_define_method(rb_cBignum, "&", rb_big_and, 1); rb_define_method(rb_cBignum, "|", rb_big_or, 1); diff --git a/lib/mathn.rb b/lib/mathn.rb index f3f7a95a48..cd4c6ef9e9 100644 --- a/lib/mathn.rb +++ b/lib/mathn.rb @@ -106,18 +106,11 @@ class Prime end class Fixnum - alias divmod! divmod - alias / rdiv - def divmod(other) - a = self.div(other) - b = self % other - return a,b - end + alias / quo end class Bignum - alias divmod! divmod - alias / rdiv + alias / quo end class Rational diff --git a/lib/rational.rb b/lib/rational.rb index 16ee00890f..af4eada071 100644 --- a/lib/rational.rb +++ b/lib/rational.rb @@ -31,8 +31,9 @@ # Integer::to_r # # Fixnum::** +# Fixnum::quo # Bignum::** -# +# Bignum::quo # def Rational(a, b = 1) @@ -312,41 +313,14 @@ class Integer end class Fixnum - alias div! /; - def div(other) - if other.kind_of?(Fixnum) - self.div!(other) - elsif other.kind_of?(Bignum) - x, y = other.coerce(self) - x.div!(y) - else - x, y = other.coerce(self) - x / y - end - end - -# alias divmod! divmod - if not defined? Complex alias power! **; end -# def rdiv(other) -# if other.kind_of?(Fixnum) -# Rational(self, other) -# elsif -# x, y = other.coerce(self) -# if defined?(x.div()) -# x.div(y) -# else -# x / y -# end -# end - # end - - def rdiv(other) + def quo(other) Rational.new!(self,1) / other end + alias rdiv quo def rpower (other) if other >= 0 @@ -362,17 +336,14 @@ class Fixnum end class Bignum - alias div! /; - alias div /; - alias divmod! divmod - if not defined? power! alias power! ** end - def rdiv(other) + def quo(other) Rational.new!(self,1) / other end + alias rdiv quo def rpower (other) if other >= 0 @@ -385,6 +356,4 @@ class Bignum if not defined? Complex alias ** rpower end - end - diff --git a/numeric.c b/numeric.c index 55e8cb6aa0..d58ea8cd90 100644 --- a/numeric.c +++ b/numeric.c @@ -57,7 +57,7 @@ #define DBL_EPSILON 2.2204460492503131e-16 #endif -static ID id_coerce, id_to_i, id_div; +static ID id_coerce, id_to_i; VALUE rb_cNumeric; VALUE rb_cFloat; @@ -169,29 +169,25 @@ num_uminus(num) return rb_funcall(zero, '-', 1, num); } +static VALUE +num_quo(x, y) + VALUE x, y; +{ + return rb_funcall(x, '/', 1, y); +} + static VALUE num_div(x, y) VALUE x, y; { - return rb_funcall(x, id_div, 1, y); + return rb_Integer(rb_funcall(x, '/', 1, y)); } static VALUE num_divmod(x, y) VALUE x, y; { - VALUE div, mod; - - div = rb_funcall(x, id_div, 1, y); - if (TYPE(div) == T_FLOAT) { - double d = floor(RFLOAT(div)->value); - - if (RFLOAT(div)->value > d) { - div = rb_float_new(d); - } - } - mod = rb_funcall(x, '%', 1, y); - return rb_assoc_new(div, mod); + return rb_assoc_new(num_div(x, y), rb_funcall(x, '%', 1, y)); } static VALUE @@ -1303,6 +1299,16 @@ fixdivmod(x, y, divp, modp) if (modp) *modp = mod; } +static VALUE +fix_quo(x, y) + VALUE x, y; +{ + if (FIXNUM_P(y)) { + return rb_float_new((double)FIX2LONG(x) / (double)FIX2LONG(y)); + } + return rb_num_coerce_bin(x, y); +} + static VALUE fix_div(x, y) VALUE x, y; @@ -1706,7 +1712,6 @@ Init_Numeric() #endif id_coerce = rb_intern("coerce"); id_to_i = rb_intern("to_i"); - id_div = rb_intern("div"); rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError); rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError); @@ -1721,7 +1726,8 @@ Init_Numeric() rb_define_method(rb_cNumeric, "===", num_equal, 1); rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); rb_define_method(rb_cNumeric, "eql?", num_eql, 1); - rb_define_method(rb_cNumeric, "/", num_div, 1); + rb_define_method(rb_cNumeric, "quo", 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); rb_define_method(rb_cNumeric, "remainder", num_remainder, 1); @@ -1776,6 +1782,7 @@ Init_Numeric() 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, "**", fix_pow, 1); rb_define_method(rb_cFixnum, "abs", fix_abs, 0);