[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]