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

ruby-changes:42223

From: nobu <ko1@a...>
Date: Sat, 26 Mar 2016 10:54:54 +0900 (JST)
Subject: [ruby-changes:42223] nobu:r54297 (trunk): numeric.c: rb_int_round

nobu	2016-03-26 10:54:50 +0900 (Sat, 26 Mar 2016)

  New Revision: 54297

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

  Log:
    numeric.c: rb_int_round
    
    * numeric.c (rb_int_round): rounding function for generic
      Integers.

  Modified files:
    trunk/ChangeLog
    trunk/internal.h
    trunk/numeric.c
Index: numeric.c
===================================================================
--- numeric.c	(revision 54296)
+++ numeric.c	(revision 54297)
@@ -106,6 +106,7 @@ round(double x) https://github.com/ruby/ruby/blob/trunk/numeric.c#L106
 static VALUE fix_uminus(VALUE num);
 static VALUE fix_mul(VALUE x, VALUE y);
 static VALUE int_pow(long x, unsigned long y);
+static VALUE int_cmp(VALUE x, VALUE y);
 
 static ID id_coerce, id_div, id_divmod;
 #define id_to_i idTo_i
@@ -177,6 +178,32 @@ compare_with_zero(VALUE num, ID mid) https://github.com/ruby/ruby/blob/trunk/numeric.c#L178
 #define FIXNUM_NEGATIVE_P(num) ((SIGNED_VALUE)(num) < 0)
 #define FIXNUM_ZERO_P(num) ((num) == INT2FIX(0))
 
+#if 0
+static inline int
+int_pos_p(VALUE num)
+{
+    if (FIXNUM_P(num)) {
+	return FIXNUM_NEGATIVE_P(num);
+    }
+    else if (RB_TYPE_P(num, T_BIGNUM)) {
+	return BIGNUM_NEGATIVE_P(num);
+    }
+    return Qnil;
+}
+#endif
+
+static inline int
+int_neg_p(VALUE num)
+{
+    if (FIXNUM_P(num)) {
+	return FIXNUM_NEGATIVE_P(num);
+    }
+    else if (RB_TYPE_P(num, T_BIGNUM)) {
+	return BIGNUM_NEGATIVE_P(num);
+    }
+    return Qnil;
+}
+
 static inline int
 positive_int_p(VALUE num)
 {
@@ -1743,12 +1770,11 @@ flo_ceil(VALUE num) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1770
 /*
  * Assumes num is an Integer, ndigits <= 0
  */
-static VALUE
-int_round_0(VALUE num, int ndigits)
+VALUE
+rb_int_round(VALUE num, int ndigits)
 {
     VALUE n, f, h, r;
     long bytes;
-    ID op;
     /* If 10**N / 2 > num, then return 0 */
     /* We have log_256(10) > 0.415241 and log_256(1/2) = -0.125, so */
     bytes = FIXNUM_P(num) ? sizeof(long) : rb_funcall(num, idSize, 0);
@@ -1769,12 +1795,12 @@ int_round_0(VALUE num, int ndigits) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1795
 	/* then int_pow overflow */
 	return INT2FIX(0);
     }
-    h = rb_funcall(f, '/', 1, INT2FIX(2));
-    r = rb_funcall(num, '%', 1, f);
-    n = rb_funcall(num, '-', 1, r);
-    op = negative_int_p(num) ? idLE : '<';
-    if (!RTEST(rb_funcall(r, op, 1, h))) {
-	n = rb_funcall(n, '+', 1, f);
+    h = rb_int_idiv(f, INT2FIX(2));
+    r = rb_int_modulo(num, f);
+    n = rb_int_minus(num, r);
+    r = int_cmp(r, h);
+    if (FIXNUM_POSITIVE_P(r) || (FIXNUM_ZERO_P(r) && !int_neg_p(num))) {
+	n = rb_int_plus(n, f);
     }
     return n;
 }
@@ -1826,7 +1852,7 @@ flo_round(int argc, VALUE *argv, VALUE n https://github.com/ruby/ruby/blob/trunk/numeric.c#L1852
 	ndigits = NUM2INT(nd);
     }
     if (ndigits < 0) {
-	return int_round_0(flo_truncate(num), ndigits);
+	return rb_int_round(flo_truncate(num), ndigits);
     }
     number  = RFLOAT_VALUE(num);
     if (ndigits == 0) {
@@ -4123,7 +4149,7 @@ int_round(int argc, VALUE* argv, VALUE n https://github.com/ruby/ruby/blob/trunk/numeric.c#L4149
     if (ndigits == 0) {
 	return num;
     }
-    return int_round_0(num, ndigits);
+    return rb_int_round(num, ndigits);
 }
 
 /*
Index: internal.h
===================================================================
--- internal.h	(revision 54296)
+++ internal.h	(revision 54297)
@@ -1013,6 +1013,7 @@ VALUE rb_int_minus(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/internal.h#L1013
 VALUE rb_int_mul(VALUE x, VALUE y);
 VALUE rb_int_idiv(VALUE x, VALUE y);
 VALUE rb_int_modulo(VALUE x, VALUE y);
+VALUE rb_int_round(VALUE num, int ndigits);
 VALUE rb_dbl_hash(double d);
 VALUE rb_fix_plus(VALUE x, VALUE y);
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54296)
+++ ChangeLog	(revision 54297)
@@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Sat Mar 26 10:54:14 2016  Nobuyoshi Nakada  <nobu@r...>
+Sat Mar 26 10:54:49 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* numeric.c (rb_int_round): rounding function for generic
+	  Integers.
 
 	* numeric.c (rb_int_{uminus,plus,minus,mul,idiv,modulo}): basic
 	  arithmetic functions for generic Integers.

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

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