rational.c: optimize Rational#**

* rational.c (nurat_expt): optimize Rational#**.
  Author: Tadashi Saito <tad.a.digger@gmail.com>

* numeric.c (rb_float_pow): rename flo_pow() to rb_float_pow()
  and remove static to be exporetd.

* internal.h (rb_int_pow, rb_float_pow): exported.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56725 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
mrkn 2016-11-11 16:38:28 +00:00
parent 75bf28bb42
commit d8769bffe5
3 changed files with 14 additions and 10 deletions

View File

@ -1171,6 +1171,8 @@ VALUE rb_fix_plus(VALUE x, VALUE y);
VALUE rb_int_ge(VALUE x, VALUE y); VALUE rb_int_ge(VALUE x, VALUE y);
enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts); enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
double rb_int_fdiv_double(VALUE x, VALUE y); double rb_int_fdiv_double(VALUE x, VALUE y);
VALUE rb_int_pow(VALUE x, VALUE y);
VALUE rb_float_pow(VALUE x, VALUE y);
#if USE_FLONUM #if USE_FLONUM
#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))

View File

@ -1291,8 +1291,8 @@ flo_divmod(VALUE x, VALUE y)
* 2.0**3 #=> 8.0 * 2.0**3 #=> 8.0
*/ */
static VALUE VALUE
flo_pow(VALUE x, VALUE y) rb_float_pow(VALUE x, VALUE y)
{ {
double dx, dy; double dx, dy;
if (RB_TYPE_P(y, T_FIXNUM)) { if (RB_TYPE_P(y, T_FIXNUM)) {
@ -3931,7 +3931,7 @@ fix_pow(VALUE x, VALUE y)
} }
} }
static VALUE VALUE
rb_int_pow(VALUE x, VALUE y) rb_int_pow(VALUE x, VALUE y)
{ {
if (FIXNUM_P(x)) { if (FIXNUM_P(x)) {
@ -5395,7 +5395,7 @@ Init_Numeric(void)
rb_define_method(rb_cFloat, "%", flo_mod, 1); rb_define_method(rb_cFloat, "%", flo_mod, 1);
rb_define_method(rb_cFloat, "modulo", flo_mod, 1); rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1); rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
rb_define_method(rb_cFloat, "**", flo_pow, 1); rb_define_method(rb_cFloat, "**", rb_float_pow, 1);
rb_define_method(rb_cFloat, "==", flo_eq, 1); rb_define_method(rb_cFloat, "==", flo_eq, 1);
rb_define_method(rb_cFloat, "===", flo_eq, 1); rb_define_method(rb_cFloat, "===", flo_eq, 1);
rb_define_method(rb_cFloat, "<=>", flo_cmp, 1); rb_define_method(rb_cFloat, "<=>", flo_cmp, 1);

View File

@ -966,6 +966,8 @@ f_odd_p(VALUE integer)
return Qfalse; return Qfalse;
} }
static VALUE nurat_to_f(VALUE self);
/* /*
* call-seq: * call-seq:
* rat ** numeric -> numeric * rat ** numeric -> numeric
@ -1022,12 +1024,12 @@ nurat_expt(VALUE self, VALUE other)
switch (FIX2INT(f_cmp(other, ZERO))) { switch (FIX2INT(f_cmp(other, ZERO))) {
case 1: case 1:
num = f_expt(dat->num, other); num = rb_int_pow(dat->num, other);
den = f_expt(dat->den, other); den = rb_int_pow(dat->den, other);
break; break;
case -1: case -1:
num = f_expt(dat->den, f_negate(other)); num = rb_int_pow(dat->den, rb_int_uminus(other));
den = f_expt(dat->num, f_negate(other)); den = rb_int_pow(dat->num, rb_int_uminus(other));
break; break;
default: default:
num = ONE; num = ONE;
@ -1039,10 +1041,10 @@ nurat_expt(VALUE self, VALUE other)
} }
else if (RB_TYPE_P(other, T_BIGNUM)) { else if (RB_TYPE_P(other, T_BIGNUM)) {
rb_warn("in a**b, b may be too big"); rb_warn("in a**b, b may be too big");
return f_expt(f_to_f(self), other); return rb_float_pow(nurat_to_f(self), other);
} }
else if (RB_TYPE_P(other, T_FLOAT) || RB_TYPE_P(other, T_RATIONAL)) { else if (RB_TYPE_P(other, T_FLOAT) || RB_TYPE_P(other, T_RATIONAL)) {
return f_expt(f_to_f(self), other); return rb_float_pow(nurat_to_f(self), other);
} }
else { else {
return rb_num_coerce_bin(self, other, id_expt); return rb_num_coerce_bin(self, other, id_expt);