summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--complex.c48
-rw-r--r--rational.c10
3 files changed, 58 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 13e6b6f..580cc49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Jun 28 19:48:29 2009 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * complex.c (nucomp_expt): some improvements.
+
+ * rational.c (nurat_expt): ditto.
+
Sun Jun 28 19:03:46 2009 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* tool/instruby.rb (:gem): registers the bundled version
diff --git a/complex.c b/complex.c
index 2e7dc16..2a7e602 100644
--- a/complex.c
+++ b/complex.c
@@ -751,6 +751,37 @@ nucomp_fdiv(VALUE self, VALUE other)
return f_divide(self, other, f_fdiv, id_fdiv);
}
+static VALUE
+m_log(VALUE x)
+{
+ if (f_real_p(x) && f_positive_p(x))
+ return m_log_bang(x);
+ return rb_complex_new2(m_log_bang(f_abs(x)), f_arg(x));
+}
+
+static VALUE
+m_exp(VALUE x)
+{
+ VALUE ere;
+
+ if (f_real_p(x))
+ return m_exp_bang(x);
+ {
+ get_dat1(x);
+ ere = m_exp_bang(dat->real);
+ return rb_complex_new2(f_mul(ere, m_cos_bang(dat->imag)),
+ f_mul(ere, m_sin_bang(dat->imag)));
+ }
+}
+
+VALUE
+rb_fexpt(VALUE x, VALUE y)
+{
+ if (f_zero_p(x) || (!k_float_p(x) && !k_float_p(y)))
+ return f_expt(x, y);
+ return m_exp(f_mul(m_log(x), y));
+}
+
/*
* call-seq:
* cmp ** numeric -> complex
@@ -769,7 +800,22 @@ nucomp_expt(VALUE self, VALUE other)
return f_complex_new_bang1(CLASS_OF(self), ONE);
if (k_rational_p(other) && f_one_p(f_denominator(other)))
- other = f_numerator(other); /* good? */
+ other = f_numerator(other); /* c14n */
+
+ if (k_complex_p(other)) {
+ get_dat1(other);
+
+ if (f_zero_p(dat->imag))
+ other = dat->real; /* c14n */
+ }
+
+ {
+ get_dat1(self);
+
+ if (f_zero_p(dat->imag) && f_real_p(other))
+ return f_complex_new1(CLASS_OF(self),
+ rb_fexpt(dat->real, other)); /* c14n */
+ }
if (k_complex_p(other)) {
VALUE r, theta, nr, ntheta;
diff --git a/rational.c b/rational.c
index 3c9ba97..90025fa 100644
--- a/rational.c
+++ b/rational.c
@@ -870,6 +870,8 @@ nurat_fdiv(VALUE self, VALUE other)
return f_to_f(f_div(self, other));
}
+extern VALUE rb_fexpt(VALUE x, VALUE y);
+
/*
* call-seq:
* rat ** numeric -> numeric_result
@@ -895,7 +897,7 @@ nurat_expt(VALUE self, VALUE other)
get_dat1(other);
if (f_one_p(dat->den))
- other = dat->num; /* good? */
+ other = dat->num; /* c14n */
}
switch (TYPE(other)) {
@@ -924,9 +926,7 @@ nurat_expt(VALUE self, VALUE other)
}
case T_FLOAT:
case T_RATIONAL:
- if (f_negative_p(self))
- return f_expt(rb_complex_new1(self), other); /* explicitly */
- return f_expt(f_to_f(self), other);
+ return rb_fexpt(f_to_f(self), other);
default:
return rb_num_coerce_bin(self, other, id_expt);
}
@@ -956,7 +956,7 @@ nurat_cmp(VALUE self, VALUE other)
get_dat1(self);
if (FIXNUM_P(dat->den) && FIX2LONG(dat->den) == 1)
- return f_cmp(dat->num, other);
+ return f_cmp(dat->num, other); /* c14n */
return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
}
case T_FLOAT: