summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 12:07:33 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 12:07:33 +0000
commit74d6b68229bd9cd85bc412309aa1a17c9529b374 (patch)
tree786d0e5492a986565a3d21dfd0b636851626344e /numeric.c
parent60eeeb70df15cc77724b454d40e02d040da8f1f1 (diff)
merge revision(s) r45187,r45205,r45206,r45212,r45213: [Backport #9570]
* numeric.c (ruby_num_interval_step_size): check signs and get rid of implementation dependent behavior of negative division. [ruby-core:61106] [Bug #9570] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@46226 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/numeric.c b/numeric.c
index 734ab3455b..de0e0a2c4d 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1799,21 +1799,29 @@ VALUE
ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl)
{
if (FIXNUM_P(from) && FIXNUM_P(to) && FIXNUM_P(step)) {
- long delta, diff, result;
+ long delta, diff;
diff = FIX2LONG(step);
+ if (!diff) rb_num_zerodiv();
delta = FIX2LONG(to) - FIX2LONG(from);
+ if (diff < 0) {
+ diff = -diff;
+ delta = -delta;
+ }
if (excl) {
- delta += (diff > 0 ? -1 : +1);
+ delta--;
+ }
+ if (delta < 0) {
+ return INT2FIX(0);
}
- result = delta / diff;
- return LONG2FIX(result >= 0 ? result + 1 : 0);
+ return ULONG2NUM(delta / diff + 1UL);
}
else if (RB_TYPE_P(from, T_FLOAT) || RB_TYPE_P(to, T_FLOAT) || RB_TYPE_P(step, T_FLOAT)) {
double n = ruby_float_step_size(NUM2DBL(from), NUM2DBL(to), NUM2DBL(step), excl);
if (isinf(n)) return DBL2NUM(n);
- return LONG2FIX(n);
+ if (POSFIXABLE(n)) return LONG2FIX(n);
+ return rb_dbl2big(n);
}
else {
VALUE result;