mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@46401 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
dcdf8e1c85
commit
00e41e7174
4 changed files with 47 additions and 16 deletions
|
@ -1,3 +1,7 @@
|
|||
Wed Jun 11 02:18:34 2014 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||
|
||||
* numeric.c: Fix Numeric#step with 0 unit [Bug #9575]
|
||||
|
||||
Wed Jun 11 00:36:05 2014 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
||||
|
||||
* test/ruby/test_string (test_LSHIFT_neary_long_max): extend timeout.
|
||||
|
|
43
numeric.c
43
numeric.c
|
@ -105,7 +105,7 @@ static VALUE fix_uminus(VALUE num);
|
|||
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)
|
|||
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 end, double unit, int excl)
|
|||
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, VALUE step, int excl)
|
|||
/* 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, VALUE to, VALUE step, int excl)
|
|||
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, VALUE to, VALUE step, int excl)
|
|||
}
|
||||
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, VALUE to, VALUE step, int excl)
|
|||
} \
|
||||
} 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 from)
|
|||
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)
|
|||
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)
|
|||
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);
|
||||
|
|
|
@ -267,6 +267,7 @@ class TestNumeric < Test::Unit::TestCase
|
|||
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
|
|||
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue