diff options
author | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-15 13:33:05 +0000 |
---|---|---|
committer | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-15 13:33:05 +0000 |
commit | 22cdd6480e5c13eb58703656eb808d21deb72081 (patch) | |
tree | aa2e2561b4b4bc1160ca4f2434bd28a6770c22f7 /array.c | |
parent | de387ef4a5635615cf3cfd774a9ebf6a4b2757f8 (diff) | |
download | ruby-22cdd6480e5c13eb58703656eb808d21deb72081.tar.gz |
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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 18 |
1 files changed, 18 insertions, 0 deletions
@@ -5722,6 +5722,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) 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 ary) 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 ary) 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) |