ruby-changes:34320
From: nagachika <ko1@a...>
Date: Wed, 11 Jun 2014 02:24:31 +0900 (JST)
Subject: [ruby-changes:34320] nagachika:r46401 (ruby_2_1): merge revision(s) r45207, r45208, r45209, r45210: [Backport #9575]
nagachika 2014-06-11 02:24:24 +0900 (Wed, 11 Jun 2014) New Revision: 46401 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46401 Log: merge revision(s) r45207,r45208,r45209,r45210: [Backport #9575] * numeric.c: Create var for rb_intern("<=>") * numeric.c: Fix Numeric#step with 0 unit [Bug #9575] Modified directories: branches/ruby_2_1/ Modified files: branches/ruby_2_1/ChangeLog branches/ruby_2_1/numeric.c branches/ruby_2_1/test/ruby/test_numeric.rb branches/ruby_2_1/version.h Index: ruby_2_1/ChangeLog =================================================================== --- ruby_2_1/ChangeLog (revision 46400) +++ ruby_2_1/ChangeLog (revision 46401) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1 +Wed Jun 11 02:18:34 2014 Marc-Andre Lafortune <ruby-core@m...> + + * numeric.c: Fix Numeric#step with 0 unit [Bug #9575] + Wed Jun 11 00:36:05 2014 CHIKANAGA Tomoyuki <nagachika@r...> * test/ruby/test_string (test_LSHIFT_neary_long_max): extend timeout. Index: ruby_2_1/numeric.c =================================================================== --- ruby_2_1/numeric.c (revision 46400) +++ ruby_2_1/numeric.c (revision 46401) @@ -105,7 +105,7 @@ static VALUE fix_uminus(VALUE num); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L105 static VALUE fix_mul(VALUE x, VALUE y); static VALUE int_pow(long x, unsigned long y); -static ID id_coerce, id_to_i, id_eq, id_div; +static ID id_coerce, id_to_i, id_eq, id_div, id_cmp; VALUE rb_cNumeric; VALUE rb_cFloat; @@ -1164,7 +1164,7 @@ flo_cmp(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1164 if (a > 0.0) return INT2FIX(1); return INT2FIX(-1); } - return rb_num_coerce_cmp(x, y, rb_intern("<=>")); + return rb_num_coerce_cmp(x, y, id_cmp); } return rb_dbl_cmp(a, b); } @@ -1754,6 +1754,9 @@ ruby_float_step_size(double beg, double https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1754 if (isinf(unit)) { return unit > 0 ? beg <= end : beg >= end; } + if (unit == 0) { + return INFINITY; + } if (err>0.5) err=0.5; if (excl) { if (n<=0) return 0; @@ -1783,6 +1786,11 @@ ruby_float_step(VALUE from, VALUE to, VA https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1786 /* if unit is infinity, i*unit+beg is NaN */ if (n) rb_yield(DBL2NUM(beg)); } + else if (unit == 0) { + VALUE val = DBL2NUM(beg); + for (;;) + rb_yield(val); + } else { for (i=0; i<n; i++) { double d = i*unit+beg; @@ -1802,7 +1810,9 @@ ruby_num_interval_step_size(VALUE from, https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1810 long delta, diff; diff = FIX2LONG(step); - if (!diff) rb_num_zerodiv(); + if (diff == 0) { + return DBL2NUM(INFINITY); + } delta = FIX2LONG(to) - FIX2LONG(from); if (diff < 0) { diff = -diff; @@ -1825,7 +1835,11 @@ ruby_num_interval_step_size(VALUE from, https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1835 } else { VALUE result; - ID cmp = RTEST(rb_funcall(step, '>', 1, INT2FIX(0))) ? '>' : '<'; + ID cmp = '>'; + switch (rb_cmpint(rb_num_coerce_cmp(step, INT2FIX(0), id_cmp), step, INT2FIX(0))) { + case 0: return DBL2NUM(INFINITY); + case -1: cmp = '<'; break; + } if (RTEST(rb_funcall(from, cmp, 1, to))) return INT2FIX(0); result = rb_funcall(rb_funcall(to, '-', 1, from), id_div, 1, step); if (!excl || RTEST(rb_funcall(rb_funcall(from, '+', 1, rb_funcall(result, '*', 1, step)), cmp, 1, to))) { @@ -1859,14 +1873,6 @@ ruby_num_interval_step_size(VALUE from, https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1873 } \ } while (0) -#define NUM_STEP_GET_INF(to, desc, inf) do { \ - if (RB_TYPE_P(to, T_FLOAT)) { \ - double f = RFLOAT_VALUE(to); \ - inf = isinf(f) && (signbit(f) ? desc : !desc); \ - } \ - else inf = 0; \ -} while (0) - static VALUE num_step_size(VALUE from, VALUE args, VALUE eobj) { @@ -1942,8 +1948,14 @@ num_step(int argc, VALUE *argv, VALUE fr https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L1948 RETURN_SIZED_ENUMERATOR(from, argc, argv, num_step_size); NUM_STEP_SCAN_ARGS(argc, argv, to, step, hash, desc); - NUM_STEP_GET_INF(to, desc, inf); - + if (RTEST(rb_num_coerce_cmp(step, INT2FIX(0), id_eq))) { + inf = 1; + } + else if (RB_TYPE_P(to, T_FLOAT)) { + double f = RFLOAT_VALUE(to); + inf = isinf(f) && (signbit(f) ? desc : !desc); + } + else inf = 0; if (FIXNUM_P(from) && (inf || FIXNUM_P(to)) && FIXNUM_P(step)) { long i = FIX2LONG(from); @@ -3136,7 +3148,7 @@ fix_cmp(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L3148 return rb_integer_float_cmp(x, y); } else { - return rb_num_coerce_cmp(x, y, rb_intern("<=>")); + return rb_num_coerce_cmp(x, y, id_cmp); } } @@ -3832,6 +3844,7 @@ Init_Numeric(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/numeric.c#L3844 id_to_i = rb_intern("to_i"); id_eq = rb_intern("=="); id_div = rb_intern("div"); + id_cmp = rb_intern("<=>"); rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError); rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError); Index: ruby_2_1/version.h =================================================================== --- ruby_2_1/version.h (revision 46400) +++ ruby_2_1/version.h (revision 46401) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1 #define RUBY_VERSION "2.1.2" #define RUBY_RELEASE_DATE "2014-06-11" -#define RUBY_PATCHLEVEL 125 +#define RUBY_PATCHLEVEL 126 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 6 Index: ruby_2_1/test/ruby/test_numeric.rb =================================================================== --- ruby_2_1/test/ruby/test_numeric.rb (revision 46400) +++ ruby_2_1/test/ruby/test_numeric.rb (revision 46401) @@ -267,6 +267,7 @@ class TestNumeric < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_numeric.rb#L267 assert_step [], [2, 1, 3] assert_step [], [-2, -1, -3] assert_step [3, 3, 3, 3], [3, by: 0], inf: true + assert_step [3, 3, 3, 3], [3, by: 0, to: 42], inf: true assert_step [10], [10, 1, -bignum] assert_step [], [1, 0, Float::INFINITY] @@ -276,6 +277,19 @@ class TestNumeric < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_numeric.rb#L277 assert_step [10, 11, 12, 13], [10], inf: true assert_step [10, 9, 8, 7], [10, by: -1], inf: true assert_step [10, 9, 8, 7], [10, by: -1, to: nil], inf: true + + assert_step [42, 42, 42, 42], [42, by: 0, to: -Float::INFINITY], inf: true + assert_step [42, 42, 42, 42], [42, by: 0, to: 42.5], inf: true + assert_step [4.2, 4.2, 4.2, 4.2], [4.2, by: 0.0], inf: true + assert_step [4.2, 4.2, 4.2, 4.2], [4.2, by: -0.0], inf: true + assert_step [42.0, 42.0, 42.0, 42.0], [42, by: 0.0, to: 44], inf: true + assert_step [42.0, 42.0, 42.0, 42.0], [42, by: 0.0, to: 0], inf: true + assert_step [42.0, 42.0, 42.0, 42.0], [42, by: -0.0, to: 44], inf: true + + assert_step [bignum]*4, [bignum, by: 0], inf: true + assert_step [bignum]*4, [bignum, by: 0.0], inf: true + assert_step [bignum]*4, [bignum, by: 0, to: bignum+1], inf: true + assert_step [bignum]*4, [bignum, by: 0, to: 0], inf: true end def test_num2long Property changes on: ruby_2_1 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r45207-45210 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/