summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-02 16:10:47 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-02 16:10:47 +0000
commit24df9a76903702303b2fb6122bbd8e7322a4e7fa (patch)
tree74a34457660eab41bc215e0299a8a3f0f25de92d /numeric.c
parent648eb6784b7935e9edb260cb1577bdaf8be771e6 (diff)
merge revision(s) r45187,r45205,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_0_0@45250 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 d37edd719f..2c15e2fbe9 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1816,21 +1816,29 @@ VALUE
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;