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/