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

ruby-changes:52401

From: nobu <ko1@a...>
Date: Sat, 1 Sep 2018 16:34:37 +0900 (JST)
Subject: [ruby-changes:52401] nobu:r64610 (trunk): complex.c: simplify division result

nobu	2018-09-01 16:34:31 +0900 (Sat, 01 Sep 2018)

  New Revision: 64610

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64610

  Log:
    complex.c: simplify division result
    
    * complex.c (f_divide): canonicalize rationals to simplify integer
      complex results.

  Modified files:
    trunk/complex.c
    trunk/internal.h
    trunk/rational.c
    trunk/test/ruby/test_complex.rb
Index: complex.c
===================================================================
--- complex.c	(revision 64609)
+++ complex.c	(revision 64610)
@@ -774,6 +774,7 @@ f_divide(VALUE self, VALUE other, https://github.com/ruby/ruby/blob/trunk/complex.c#L774
 	 VALUE (*func)(VALUE, VALUE), ID id)
 {
     if (RB_TYPE_P(other, T_COMPLEX)) {
+        VALUE r, n, x, y;
 	int flo;
 	get_dat2(self, other);
 
@@ -781,35 +782,28 @@ f_divide(VALUE self, VALUE other, https://github.com/ruby/ruby/blob/trunk/complex.c#L782
 	       RB_FLOAT_TYPE_P(bdat->real) || RB_FLOAT_TYPE_P(bdat->imag));
 
 	if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
-	    VALUE r, n;
-
 	    r = (*func)(bdat->imag, bdat->real);
 	    n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
 	    if (flo)
 		return f_complex_new2(CLASS_OF(self),
 				      (*func)(self, n),
 				      (*func)(f_negate(f_mul(self, r)), n));
-	    return f_complex_new2(CLASS_OF(self),
-				  (*func)(f_add(adat->real,
-						f_mul(adat->imag, r)), n),
-				  (*func)(f_sub(adat->imag,
-						f_mul(adat->real, r)), n));
+            x = (*func)(f_add(adat->real, f_mul(adat->imag, r)), n);
+            y = (*func)(f_sub(adat->imag, f_mul(adat->real, r)), n);
 	}
 	else {
-	    VALUE r, n;
-
 	    r = (*func)(bdat->real, bdat->imag);
 	    n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
 	    if (flo)
 		return f_complex_new2(CLASS_OF(self),
 				      (*func)(f_mul(self, r), n),
 				      (*func)(f_negate(self), n));
-	    return f_complex_new2(CLASS_OF(self),
-				  (*func)(f_add(f_mul(adat->real, r),
-						adat->imag), n),
-				  (*func)(f_sub(f_mul(adat->imag, r),
-						adat->real), n));
+            x = (*func)(f_add(f_mul(adat->real, r), adat->imag), n);
+            y = (*func)(f_sub(f_mul(adat->imag, r), adat->real), n);
 	}
+        x = rb_rational_canonicalize(x);
+        y = rb_rational_canonicalize(y);
+        return f_complex_new2(CLASS_OF(self), x, y);
     }
     if (k_numeric_p(other) && f_real_p(other)) {
 	get_dat1(self);
Index: internal.h
===================================================================
--- internal.h	(revision 64609)
+++ internal.h	(revision 64610)
@@ -1729,6 +1729,7 @@ rb_pid_t rb_fork_ruby(int *status); https://github.com/ruby/ruby/blob/trunk/internal.h#L1729
 void rb_last_status_clear(void);
 
 /* rational.c */
+VALUE rb_rational_canonicalize(VALUE x);
 VALUE rb_rational_uminus(VALUE self);
 VALUE rb_rational_plus(VALUE self, VALUE other);
 VALUE rb_lcm(VALUE x, VALUE y);
Index: test/ruby/test_complex.rb
===================================================================
--- test/ruby/test_complex.rb	(revision 64609)
+++ test/ruby/test_complex.rb	(revision 64610)
@@ -323,6 +323,13 @@ class Complex_Test < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/ruby/test_complex.rb#L323
 
     assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
     assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
+
+    c = Complex(1)
+    r = c / c
+    assert_instance_of(Complex, r)
+    assert_equal(1, r)
+    assert_predicate(r.real, :integer?)
+    assert_predicate(r.imag, :integer?)
   end
 
   def test_quo
Index: rational.c
===================================================================
--- rational.c	(revision 64609)
+++ rational.c	(revision 64610)
@@ -1991,6 +1991,15 @@ rb_numeric_quo(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/rational.c#L1991
     return nurat_div(x, y);
 }
 
+VALUE
+rb_rational_canonicalize(VALUE x)
+{
+    if (RB_TYPE_P(x, T_RATIONAL)) {
+        get_dat1(x);
+        if (f_one_p(dat->den)) return dat->num;
+    }
+    return x;
+}
 
 /*
  * call-seq:

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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