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

ruby-changes:37662

From: nobu <ko1@a...>
Date: Wed, 25 Feb 2015 15:49:09 +0900 (JST)
Subject: [ruby-changes:37662] nobu:r49743 (trunk): complex.c: move optimization

nobu	2015-02-25 15:48:55 +0900 (Wed, 25 Feb 2015)

  New Revision: 49743

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

  Log:
    complex.c: move optimization
    
    * complex.c (f_complex_polar): move optimization for orthogonal
      cases from rb_nucomp_mul.

  Modified files:
    trunk/complex.c
Index: complex.c
===================================================================
--- complex.c	(revision 49742)
+++ complex.c	(revision 49743)
@@ -18,6 +18,7 @@ https://github.com/ruby/ruby/blob/trunk/complex.c#L18
 #define ZERO INT2FIX(0)
 #define ONE INT2FIX(1)
 #define TWO INT2FIX(2)
+#define RFLOAT_0 DBL2NUM(0)
 
 VALUE rb_cComplex;
 
@@ -342,6 +343,8 @@ nucomp_canonicalization(int f) https://github.com/ruby/ruby/blob/trunk/complex.c#L343
 {
     canonicalization = f;
 }
+#else
+#define canonicalization 0
 #endif
 
 inline static void
@@ -555,11 +558,44 @@ m_sqrt(VALUE x) https://github.com/ruby/ruby/blob/trunk/complex.c#L558
 }
 #endif
 
-inline static VALUE
+static VALUE
 f_complex_polar(VALUE klass, VALUE x, VALUE y)
 {
     assert(!k_complex_p(x));
     assert(!k_complex_p(y));
+    if (f_zero_p(x) || f_zero_p(y)) {
+	if (canonicalization) return x;
+	return nucomp_s_new_internal(klass, x, RFLOAT_0);
+    }
+    if (RB_FLOAT_TYPE_P(y)) {
+	const double arg = RFLOAT_VALUE(y);
+	if (arg == M_PI) {
+	    x = f_negate(x);
+	    if (canonicalization) return x;
+	    y = RFLOAT_0;
+	}
+	else if (arg == M_PI_2) {
+	    y = x;
+	    x = RFLOAT_0;
+	}
+	else if (arg == M_PI_2+M_PI) {
+	    y = f_negate(x);
+	    x = RFLOAT_0;
+	}
+	else if (RB_FLOAT_TYPE_P(x)) {
+	    const double abs = RFLOAT_VALUE(x);
+	    const double real = abs * cos(arg), imag = abs * sin(arg);
+	    x = DBL2NUM(real);
+	    if (canonicalization && imag == 0.0) return x;
+	    y = DBL2NUM(imag);
+	}
+	else {
+	    x = f_mul(x, DBL2NUM(cos(arg)));
+	    y = f_mul(y, DBL2NUM(sin(arg)));
+	    if (canonicalization && f_zero_p(y)) return x;
+	}
+	return nucomp_s_new_internal(klass, x, y);
+    }
     return nucomp_s_canonicalize_internal(klass,
 					  f_mul(x, m_cos(y)),
 					  f_mul(x, m_sin(y)));
@@ -584,8 +620,8 @@ nucomp_s_polar(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/complex.c#L620
     switch (rb_scan_args(argc, argv, "11", &abs, &arg)) {
       case 1:
 	nucomp_real_check(abs);
-	arg = ZERO;
-	break;
+	if (canonicalization) return abs;
+	return nucomp_s_new_internal(klass, abs, ZERO);
       default:
 	nucomp_real_check(abs);
 	nucomp_real_check(arg);
@@ -732,32 +768,7 @@ rb_nucomp_mul(VALUE self, VALUE other) https://github.com/ruby/ruby/blob/trunk/complex.c#L768
 	    (RB_FLOAT_TYPE_P(imag) && isnan(RFLOAT_VALUE(imag)))) {
 	    VALUE abs = f_mul(nucomp_abs(self), nucomp_abs(other));
 	    VALUE arg = f_add(nucomp_arg(self), nucomp_arg(other));
-	    if (f_zero_p(arg)) {
-		real = abs;
-		imag = INT2FIX(0);
-	    }
-	    else if (RB_FLOAT_TYPE_P(arg)) {
-		double a = RFLOAT_VALUE(arg);
-		if (a == M_PI) {
-		    real = f_negate(abs);
-		    imag = INT2FIX(0);
-		}
-		else if (a == M_PI/2) {
-		    imag = abs;
-		    real = INT2FIX(0);
-		}
-		else if (a == M_PI*3/2) {
-		    imag = f_negate(abs);
-		    real = INT2FIX(0);
-		}
-		else {
-		    goto polar;
-		}
-	    }
-	    else {
-	      polar:
-		return f_complex_polar(CLASS_OF(self), abs, arg);
-	    }
+	    return f_complex_polar(CLASS_OF(self), abs, arg);
 	}
 
 	return f_complex_new2(CLASS_OF(self), real, imag);

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

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