summaryrefslogtreecommitdiff
path: root/complex.c
diff options
context:
space:
mode:
authortadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-28 10:50:39 +0000
committertadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-28 10:50:39 +0000
commitf365778c263db6a3d02f3c2fcf676e8964a4674e (patch)
tree1103924d1cf1e893812cdd2323dbc7d420397748 /complex.c
parentc97f55efa5a7cd96e047d585f1270193acd784fb (diff)
downloadbundler-f365778c263db6a3d02f3c2fcf676e8964a4674e.tar.gz
* complex.c (nucomp_expt): some improvements.
* rational.c (nurat_expt): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23881 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'complex.c')
-rw-r--r--complex.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/complex.c b/complex.c
index 2e7dc16973..2a7e602ed1 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;