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:
parent
75bf28bb42
commit
d8769bffe5
@ -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)))
|
||||||
|
@ -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);
|
||||||
|
14
rational.c
14
rational.c
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user