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/