[前][次][番号順一覧][スレッド一覧]

ruby-changes:44669

From: mrkn <ko1@a...>
Date: Sat, 12 Nov 2016 15:45:16 +0900 (JST)
Subject: [ruby-changes:44669] mrkn:r56742 (trunk): rational.c: optimize Rational#{floor, ceil, round, truncate}

mrkn	2016-11-12 15:45:11 +0900 (Sat, 12 Nov 2016)

  New Revision: 56742

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56742

  Log:
    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@g...>
    
    * 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.

  Modified files:
    trunk/internal.h
    trunk/numeric.c
    trunk/rational.c
Index: internal.h
===================================================================
--- internal.h	(revision 56741)
+++ internal.h	(revision 56742)
@@ -1176,6 +1176,8 @@ VALUE rb_int_pow(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/internal.h#L1176
 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)))
Index: rational.c
===================================================================
--- rational.c	(revision 56741)
+++ rational.c	(revision 56742)
@@ -156,7 +156,7 @@ fun2(expt) https://github.com/ruby/ruby/blob/trunk/rational.c#L156
 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 https://github.com/ruby/ruby/blob/trunk/rational.c#L1214
 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) https://github.com/ruby/ruby/blob/trunk/rational.c#L1257
 
     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) https://github.com/ruby/ruby/blob/trunk/rational.c#L1281
 
     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, VA https://github.com/ruby/ruby/blob/trunk/rational.c#L1313
 	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, VA https://github.com/ruby/ruby/blob/trunk/rational.c#L1327
 
     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;
 }
Index: numeric.c
===================================================================
--- numeric.c	(revision 56741)
+++ numeric.c	(revision 56742)
@@ -3800,8 +3800,8 @@ fix_divmod(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L3800
     }
 }
 
-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) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4275
     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 b https://github.com/ruby/ruby/blob/trunk/numeric.c#L4743
 
     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) https://github.com/ruby/ruby/blob/trunk/numeric.c#L5246
     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) https://github.com/ruby/ruby/blob/trunk/numeric.c#L5261
     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);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]