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

ruby-changes:21848

From: naruse <ko1@a...>
Date: Wed, 30 Nov 2011 02:29:54 +0900 (JST)
Subject: [ruby-changes:21848] naruse:r33897 (ruby_1_9_3): merge revision(s) 33183,33185:

naruse	2011-11-30 02:29:41 +0900 (Wed, 30 Nov 2011)

  New Revision: 33897

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33897

  Log:
    merge revision(s) 33183,33185:
    
    * numeric.c (int_round): Integer#round always returns an Integer [Bug
      #5271]

  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/numeric.c
    branches/ruby_1_9_3/version.h

Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 33896)
+++ ruby_1_9_3/ChangeLog	(revision 33897)
@@ -1,3 +1,8 @@
+Wed Nov 30 02:28:22 2011  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* numeric.c (int_round): Integer#round always returns an Integer [Bug
+	  #5271]
+
 Fri Nov  4 01:56:30 2011  NAKAMURA Usaku  <usa@r...>
 
 	* io.c (make_writeconv): unversal_newline converter is for reading.
Index: ruby_1_9_3/numeric.c
===================================================================
--- ruby_1_9_3/numeric.c	(revision 33896)
+++ ruby_1_9_3/numeric.c	(revision 33897)
@@ -1456,6 +1456,45 @@
 }
 
 /*
+ * Assumes num is an Integer, ndigits <= 0
+ */
+static VALUE
+int_round_0(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, rb_intern("size"), 0);
+    if (-0.415241 * ndigits - 0.125 > bytes ) {
+	return INT2FIX(0);
+    }
+
+    f = int_pow(10, -ndigits);
+    if (FIXNUM_P(num) && FIXNUM_P(f)) {
+	SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
+	int neg = x < 0;
+	if (neg) x = -x;
+	x = (x + y / 2) / y * y;
+	if (neg) x = -x;
+	return LONG2NUM(x);
+    }
+    if (TYPE(f) == T_FLOAT) {
+	/* 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 = RTEST(rb_funcall(num, '<', 1, INT2FIX(0))) ? rb_intern("<=") : '<';
+    if (!RTEST(rb_funcall(r, op, 1, h))) {
+	n = rb_funcall(n, '+', 1, f);
+    }
+    return n;
+}
+
+/*
  *  call-seq:
  *     flt.round([ndigits])  ->  integer or float
  *
@@ -3318,9 +3357,8 @@
 static VALUE
 int_round(int argc, VALUE* argv, VALUE num)
 {
-    VALUE n, f, h, r;
+    VALUE n;
     int ndigits;
-    ID op;
 
     if (argc == 0) return num;
     rb_scan_args(argc, argv, "1", &n);
@@ -3331,27 +3369,7 @@
     if (ndigits == 0) {
 	return num;
     }
-    ndigits = -ndigits;
-    if (ndigits < 0) {
-	rb_raise(rb_eArgError, "ndigits out of range");
-    }
-    f = int_pow(10, ndigits);
-    if (FIXNUM_P(num) && FIXNUM_P(f)) {
-	SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
-	int neg = x < 0;
-	if (neg) x = -x;
-	x = (x + y / 2) / y * y;
-	if (neg) x = -x;
-	return LONG2NUM(x);
-    }
-    h = rb_funcall(f, '/', 1, INT2FIX(2));
-    r = rb_funcall(num, '%', 1, f);
-    n = rb_funcall(num, '-', 1, r);
-    op = RTEST(rb_funcall(num, '<', 1, INT2FIX(0))) ? rb_intern("<=") : '<';
-    if (!RTEST(rb_funcall(r, op, 1, h))) {
-	n = rb_funcall(n, '+', 1, f);
-    }
-    return n;
+    return int_round_0(num, ndigits);
 }
 
 /*
Index: ruby_1_9_3/version.h
===================================================================
--- ruby_1_9_3/version.h	(revision 33896)
+++ ruby_1_9_3/version.h	(revision 33897)
@@ -1,10 +1,10 @@
 #define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 0
+#define RUBY_PATCHLEVEL 1
 
-#define RUBY_RELEASE_DATE "2011-11-08"
+#define RUBY_RELEASE_DATE "2011-11-30"
 #define RUBY_RELEASE_YEAR 2011
 #define RUBY_RELEASE_MONTH 11
-#define RUBY_RELEASE_DAY 8
+#define RUBY_RELEASE_DAY 30
 
 #include "ruby/version.h"
 

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

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