From 9bb3022475a3026353ba6716724486630d10d899 Mon Sep 17 00:00:00 2001 From: mrkn Date: Sat, 12 Nov 2016 06:45:11 +0000 Subject: [PATCH] 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 * 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 --- internal.h | 2 ++ numeric.c | 14 +++++++------- rational.c | 44 ++++++++++++++++++++++---------------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/internal.h b/internal.h index 5b17c734db..6a7f039cd0 100644 --- a/internal.h +++ b/internal.h @@ -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))) diff --git a/numeric.c b/numeric.c index 8dd05afefd..e0d6358932 100644 --- a/numeric.c +++ b/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); diff --git a/rational.c b/rational.c index c55081a143..d9363a2e5f 100644 --- a/rational.c +++ b/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; }