diff options
author | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-11-18 15:17:19 +0000 |
---|---|---|
committer | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-11-18 15:17:19 +0000 |
commit | c151aa88a97d5f3a95c77e7de5db87b7acec16bb (patch) | |
tree | 523f90b6abc0ba5848552494e1efb1fb3ebbcbbf /complex.c | |
parent | 632622731722133bbbad7e65878a6cbbb228c5a3 (diff) |
complex.c: optimize f_negate
* complex.c (f_negate): optimize for special numeric types.
* complex.c (nucomp_expt): use rb_int_uminus instead of f_negate for
fixnum value.
* internal.h (rb_float_uminus, rb_rational_uminus): exported.
* numeric.c (rb_float_uminus): rename from flo_uminus.
* rational.c (rb_rational_uminus): rename from nurat_negate, and add
assertion for the parameter.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56830 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'complex.c')
-rw-r--r-- | complex.c | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -144,7 +144,27 @@ f_sub(VALUE x, VALUE y) fun1(abs) fun1(arg) fun1(denominator) -fun1(negate) + +static VALUE nucomp_negate(VALUE self); + +inline static VALUE +f_negate(VALUE x) +{ + if (RB_INTEGER_TYPE_P(x)) { + return rb_int_uminus(x); + } + else if (RB_FLOAT_TYPE_P(x)) { + return rb_float_uminus(x); + } + else if (RB_TYPE_P(x, T_RATIONAL)) { + return rb_rational_uminus(x); + } + else if (RB_TYPE_P(x, T_COMPLEX)) { + return nucomp_negate(x); + } + return rb_funcall(x, id_negate, 0); +} + fun1(numerator) fun1(real_p) @@ -917,7 +937,7 @@ nucomp_expt(VALUE self, VALUE other) } return z; } - return f_expt(f_reciprocal(self), f_negate(other)); + return f_expt(f_reciprocal(self), rb_int_uminus(other)); } if (k_numeric_p(other) && f_real_p(other)) { VALUE r, theta; |