mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
rational.c: optimize Rational#{floor,ceil,round,truncate}
* rational.c (f_{expt10,round_common},nurat_{floor,ceil,round_half_{up,even}}): optimize Rational#{floor,ceil,round,truncate}. Author: Tadashi Saito <tad.a.digger@gmail.com> * numeric.c (rb_int_divmod): rename from int_divmod to be exported. * numeric.c (rb_int_and): rename from int_and to be exported. * intern.h (rb_int_{divmod,and}): exported. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56742 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a5160c5051
commit
9bb3022475
3 changed files with 31 additions and 29 deletions
|
@ -1176,6 +1176,8 @@ VALUE rb_int_pow(VALUE x, VALUE y);
|
|||
VALUE rb_float_pow(VALUE x, VALUE y);
|
||||
VALUE rb_int_cmp(VALUE x, VALUE y);
|
||||
VALUE rb_int_equal(VALUE x, VALUE y);
|
||||
VALUE rb_int_divmod(VALUE x, VALUE y);
|
||||
VALUE rb_int_and(VALUE x, VALUE y);
|
||||
|
||||
#if USE_FLONUM
|
||||
#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
|
||||
|
|
14
numeric.c
14
numeric.c
|
@ -3800,8 +3800,8 @@ fix_divmod(VALUE x, VALUE y)
|
|||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
int_divmod(VALUE x, VALUE y)
|
||||
VALUE
|
||||
rb_int_divmod(VALUE x, VALUE y)
|
||||
{
|
||||
if (FIXNUM_P(x)) {
|
||||
return fix_divmod(x, y);
|
||||
|
@ -4275,8 +4275,8 @@ fix_and(VALUE x, VALUE y)
|
|||
return rb_num_coerce_bit(x, y, '&');
|
||||
}
|
||||
|
||||
static VALUE
|
||||
int_and(VALUE x, VALUE y)
|
||||
VALUE
|
||||
rb_int_and(VALUE x, VALUE y)
|
||||
{
|
||||
if (FIXNUM_P(x)) {
|
||||
return fix_and(x, y);
|
||||
|
@ -4743,7 +4743,7 @@ rb_int_digits_bigbase(VALUE num, VALUE base)
|
|||
|
||||
digits = rb_ary_new();
|
||||
while (!FIXNUM_P(num) || FIX2LONG(num) > 0) {
|
||||
VALUE qr = int_divmod(num, base);
|
||||
VALUE qr = rb_int_divmod(num, base);
|
||||
rb_ary_push(digits, RARRAY_AREF(qr, 1));
|
||||
num = RARRAY_AREF(qr, 0);
|
||||
}
|
||||
|
@ -5246,7 +5246,7 @@ Init_Numeric(void)
|
|||
rb_define_method(rb_cInteger, "%", rb_int_modulo, 1);
|
||||
rb_define_method(rb_cInteger, "modulo", rb_int_modulo, 1);
|
||||
rb_define_method(rb_cInteger, "remainder", int_remainder, 1);
|
||||
rb_define_method(rb_cInteger, "divmod", int_divmod, 1);
|
||||
rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1);
|
||||
rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1);
|
||||
rb_define_method(rb_cInteger, "**", rb_int_pow, 1);
|
||||
|
||||
|
@ -5261,7 +5261,7 @@ Init_Numeric(void)
|
|||
rb_define_method(rb_cInteger, "<=", int_le, 1);
|
||||
|
||||
rb_define_method(rb_cInteger, "~", int_comp, 0);
|
||||
rb_define_method(rb_cInteger, "&", int_and, 1);
|
||||
rb_define_method(rb_cInteger, "&", rb_int_and, 1);
|
||||
rb_define_method(rb_cInteger, "|", int_or, 1);
|
||||
rb_define_method(rb_cInteger, "^", int_xor, 1);
|
||||
rb_define_method(rb_cInteger, "[]", int_aref, 1);
|
||||
|
|
44
rational.c
44
rational.c
|
@ -156,7 +156,7 @@ fun2(expt)
|
|||
fun2(fdiv)
|
||||
fun2(idiv)
|
||||
|
||||
#define f_expt10(x) f_expt(INT2FIX(10), x)
|
||||
#define f_expt10(x) rb_int_pow(INT2FIX(10), x)
|
||||
|
||||
inline static int
|
||||
f_negative_p(VALUE x)
|
||||
|
@ -1214,14 +1214,14 @@ static VALUE
|
|||
nurat_floor(VALUE self)
|
||||
{
|
||||
get_dat1(self);
|
||||
return f_idiv(dat->num, dat->den);
|
||||
return rb_int_idiv(dat->num, dat->den);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nurat_ceil(VALUE self)
|
||||
{
|
||||
get_dat1(self);
|
||||
return f_negate(f_idiv(f_negate(dat->num), dat->den));
|
||||
return rb_int_uminus(rb_int_idiv(rb_int_uminus(dat->num), dat->den));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1257,17 +1257,17 @@ nurat_round_half_up(VALUE self)
|
|||
|
||||
num = dat->num;
|
||||
den = dat->den;
|
||||
neg = f_negative_p(num);
|
||||
neg = INT_NEGATIVE_P(num);
|
||||
|
||||
if (neg)
|
||||
num = f_negate(num);
|
||||
num = rb_int_uminus(num);
|
||||
|
||||
num = f_add(f_mul(num, TWO), den);
|
||||
den = f_mul(den, TWO);
|
||||
num = f_idiv(num, den);
|
||||
num = rb_int_plus(rb_int_mul(num, TWO), den);
|
||||
den = rb_int_mul(den, TWO);
|
||||
num = rb_int_idiv(num, den);
|
||||
|
||||
if (neg)
|
||||
num = f_negate(num);
|
||||
num = rb_int_uminus(num);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
@ -1281,20 +1281,20 @@ nurat_round_half_even(VALUE self)
|
|||
|
||||
num = dat->num;
|
||||
den = dat->den;
|
||||
neg = f_negative_p(num);
|
||||
neg = INT_NEGATIVE_P(num);
|
||||
|
||||
if (neg)
|
||||
num = f_negate(num);
|
||||
num = rb_int_uminus(num);
|
||||
|
||||
num = f_add(f_mul(num, TWO), den);
|
||||
den = f_mul(den, TWO);
|
||||
qr = rb_funcall(num, rb_intern("divmod"), 1, den);
|
||||
num = rb_int_plus(rb_int_mul(num, TWO), den);
|
||||
den = rb_int_mul(den, TWO);
|
||||
qr = rb_int_divmod(num, den);
|
||||
num = RARRAY_AREF(qr, 0);
|
||||
if (f_zero_p(RARRAY_AREF(qr, 1)))
|
||||
num = rb_funcall(num, '&', 1, LONG2FIX(((int)~1)));
|
||||
if (INT_ZERO_P(RARRAY_AREF(qr, 1)))
|
||||
num = rb_int_and(num, LONG2FIX(((int)~1)));
|
||||
|
||||
if (neg)
|
||||
num = f_negate(num);
|
||||
num = rb_int_uminus(num);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
@ -1313,10 +1313,10 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
|||
rb_raise(rb_eTypeError, "not an integer");
|
||||
|
||||
b = f_expt10(n);
|
||||
s = f_mul(self, b);
|
||||
s = nurat_mul(self, b);
|
||||
|
||||
if (k_float_p(s)) {
|
||||
if (f_lt_p(n, ZERO))
|
||||
if (INT_NEGATIVE_P(n))
|
||||
return ZERO;
|
||||
return self;
|
||||
}
|
||||
|
@ -1327,10 +1327,10 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
|||
|
||||
s = (*func)(s);
|
||||
|
||||
s = f_div(f_rational_new_bang1(CLASS_OF(self), s), b);
|
||||
s = nurat_div(f_rational_new_bang1(CLASS_OF(self), s), b);
|
||||
|
||||
if (f_lt_p(n, ONE))
|
||||
s = f_to_i(s);
|
||||
if (RB_TYPE_P(s, T_RATIONAL) && FIX2INT(rb_int_cmp(n, ONE)) < 0)
|
||||
s = nurat_truncate(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue