summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-27 14:11:19 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-27 14:11:19 +0000
commitba757763464cb3cd344454bb8d8e062ca92d2a3d (patch)
treeb7a832a8b1049393093d8f340952e2d6b32b48b8
parent95abe79e04c3238ea2dde68ea1ab567e354aad21 (diff)
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_4@64562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--array.c14
-rw-r--r--enum.c19
-rw-r--r--test/ruby/test_array.rb7
-rw-r--r--test/ruby/test_enum.rb15
-rw-r--r--version.h2
5 files changed, 56 insertions, 1 deletions
diff --git a/array.c b/array.c
index 724cf46b38..35c63fe857 100644
--- a/array.c
+++ b/array.c
@@ -5825,6 +5825,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);
diff --git a/enum.c b/enum.c
index c535b54aac..37eac56e06 100644
--- a/enum.c
+++ b/enum.c
@@ -3730,6 +3730,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);
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 42830063b5..2297ab01bc 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -2835,6 +2835,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([]))
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 468a32a9a1..dd2357602f 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -909,6 +909,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([]))
diff --git a/version.h b/version.h
index 5058df988b..a668c14354 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.4.5"
#define RUBY_RELEASE_DATE "2018-08-27"
-#define RUBY_PATCHLEVEL 319
+#define RUBY_PATCHLEVEL 320
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 8