merge revision(s) 64014: [Backport #14926]

fix sum on infinity

	* array.c (rb_ary_sum): consider non-finite floats.
	  [ruby-core:88024] [Bug #14926]

	* enum.c (sum_iter): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@64603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagachika 2018-09-01 02:31:27 +00:00
parent f63697432e
commit 2c26edc15c
5 changed files with 56 additions and 1 deletions

14
array.c
View file

@ -5954,6 +5954,20 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
else
goto not_float;
if (isnan(f)) continue;
if (isnan(x)) {
f = x;
continue;
}
if (isinf(x)) {
if (isinf(f) && signbit(x) != signbit(f))
f = NAN;
else
f = x;
continue;
}
if (isinf(f)) continue;
t = f + x;
if (fabs(f) >= fabs(x))
c += ((f - t) + x);

19
enum.c
View file

@ -3804,6 +3804,25 @@ sum_iter(VALUE i, struct enum_sum_memo *memo)
goto some_value;
}
if (isnan(f)) return;
if (isnan(x)) {
memo->v = i;
memo->f = x;
return;
}
if (isinf(x)) {
if (isinf(f) && signbit(x) != signbit(f)) {
memo->f = NAN;
memo->v = DBL2NUM(f);
}
else {
memo->f = x;
memo->v = i;
}
return;
}
if (isinf(f)) return;
t = f + x;
if (fabs(f) >= fabs(x))
c += ((f - t) + x);

View file

@ -2956,6 +2956,13 @@ class TestArray < Test::Unit::TestCase
assert_float_equal(large_number+(small_number*10), [large_number/1r, *[small_number]*10].sum)
assert_float_equal(large_number+(small_number*11), [small_number, large_number/1r, *[small_number]*10].sum)
assert_float_equal(small_number, [large_number, small_number, -large_number].sum)
assert_equal(+Float::INFINITY, [+Float::INFINITY].sum)
assert_equal(+Float::INFINITY, [0.0, +Float::INFINITY].sum)
assert_equal(+Float::INFINITY, [+Float::INFINITY, 0.0].sum)
assert_equal(-Float::INFINITY, [-Float::INFINITY].sum)
assert_equal(-Float::INFINITY, [0.0, -Float::INFINITY].sum)
assert_equal(-Float::INFINITY, [-Float::INFINITY, 0.0].sum)
assert_predicate([-Float::INFINITY, Float::INFINITY].sum, :nan?)
assert_equal("abc", ["a", "b", "c"].sum(""))
assert_equal([1, [2], 3], [[1], [[2]], [3]].sum([]))

View file

@ -966,6 +966,21 @@ class TestEnumerable < Test::Unit::TestCase
assert_float_equal(large_number+(small_number*11), [small_number, large_number/1r, *[small_number]*10].each.sum)
assert_float_equal(small_number, [large_number, small_number, -large_number].each.sum)
k = Class.new do
include Enumerable
def initialize(*values)
@values = values
end
def each(&block)
@values.each(&block)
end
end
assert_equal(+Float::INFINITY, k.new(0.0, +Float::INFINITY).sum)
assert_equal(+Float::INFINITY, k.new(+Float::INFINITY, 0.0).sum)
assert_equal(-Float::INFINITY, k.new(0.0, -Float::INFINITY).sum)
assert_equal(-Float::INFINITY, k.new(-Float::INFINITY, 0.0).sum)
assert_predicate(k.new(-Float::INFINITY, Float::INFINITY).sum, :nan?)
assert_equal("abc", ["a", "b", "c"].each.sum(""))
assert_equal([1, [2], 3], [[1], [[2]], [3]].each.sum([]))
end

View file

@ -1,6 +1,6 @@
#define RUBY_VERSION "2.5.2"
#define RUBY_RELEASE_DATE "2018-09-01"
#define RUBY_PATCHLEVEL 83
#define RUBY_PATCHLEVEL 84
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 9