ruby-changes:42527
From: mrkn <ko1@a...>
Date: Fri, 15 Apr 2016 21:36:28 +0900 (JST)
Subject: [ruby-changes:42527] mrkn:r54601 (trunk): array.c: sum for Rational and Float mixed arrays
mrkn 2016-04-15 22:33:05 +0900 (Fri, 15 Apr 2016) New Revision: 54601 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54601 Log: array.c: sum for Rational and Float mixed arrays * array.c (rb_ary_sum): apply the precision compensated algorithm for an array in which Rational and Float values are mixed. * test/ruby/test_array.rb (test_sum): add assertions for the above change. Modified files: trunk/ChangeLog trunk/array.c trunk/test/ruby/test_array.rb Index: array.c =================================================================== --- array.c (revision 54600) +++ array.c (revision 54601) @@ -5722,6 +5722,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5722 if (RB_FLOAT_TYPE_P(e)) { /* Kahan's compensated summation algorithm */ double f, c; + + float_value: f = NUM2DBL(v); c = 0.0; for (; i < RARRAY_LEN(ary); i++) { @@ -5735,6 +5737,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5737 x = FIX2LONG(e); else if (RB_TYPE_P(e, T_BIGNUM)) x = rb_big2dbl(e); + else if (RB_TYPE_P(e, T_RATIONAL)) + x = rb_num2dbl(e); else goto not_float; @@ -5749,6 +5753,20 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5753 v = DBL2NUM(f); } + if (RB_TYPE_P(e, T_RATIONAL)) { + for (; i < RARRAY_LEN(ary); i++) { + e = RARRAY_AREF(ary, i); + if (block_given) + e = rb_yield(e); + if (RB_FLOAT_TYPE_P(e)) { + v = rb_to_float(v); + goto float_value; + } + v = rb_funcall(v, idPLUS, 1, e); + } + return v; + } + for (; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) Index: ChangeLog =================================================================== --- ChangeLog (revision 54600) +++ ChangeLog (revision 54601) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Apr 15 22:31:00 2016 Kenta Murata <mrkn@m...> + + * array.c (rb_ary_sum): apply the precision compensated algorithm + for an array in which Rational and Float values are mixed. + + * test/ruby/test_array.rb (test_sum): add assertions for the above + change. + Fri Apr 15 22:30:01 2016 Nobuyoshi Nakada <nobu@r...> * thread.c (rb_thread_setname): defer setting native thread name Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 54600) +++ test/ruby/test_array.rb (revision 54601) @@ -2774,6 +2774,8 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L2774 small_number /= 10 end assert_float_equal(large_number+(small_number*10), [large_number, *[small_number]*10].sum) + 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) end private -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/