sum(p1 = v1)
public
Returns the sum of elements. For example,
[e1, e2, e3].sum returns init + e1 + e2 + e3.
If a block is given, the block is applied to each element before addition.
If ary is empty, it returns init.
[].sum
[].sum(0.0)
[1, 2, 3].sum
[3, 5.5].sum
[2.5, 3.0].sum(0.0) {|e| e * e }
[Object.new].sum
The (arithmetic) mean value of an array can be obtained as follows.
mean = ary.sum(0.0) / ary.length
This method can be used for non-numeric objects by explicit init
argument.
["a", "b", "c"].sum("")
[[1], [[2]], [3]].sum([])
However, Array#join and Array#flatten is faster than Array#sum for array of strings and array of
arrays.
["a", "b", "c"].join
[[1], [[2]], [3]].flatten(1)
Array#sum method may not respect method
redefinition of “+” methods such as Integer#+.
Show source
static VALUE
rb_ary_sum(int argc, VALUE *argv, VALUE ary)
{
VALUE e, v, r;
long i, n;
int block_given;
if (rb_scan_args(argc, argv, "01", &v) == 0)
v = LONG2FIX(0);
block_given = rb_block_given_p();
if (RARRAY_LEN(ary) == 0)
return v;
n = 0;
r = Qundef;
for (i = 0; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (FIXNUM_P(e)) {
n += FIX2LONG(e); /* should not overflow long type */
if (!FIXABLE(n)) {
v = rb_big_plus(LONG2NUM(n), v);
n = 0;
}
}
else if (RB_TYPE_P(e, T_BIGNUM))
v = rb_big_plus(e, v);
else if (RB_TYPE_P(e, T_RATIONAL)) {
if (r == Qundef)
r = e;
else
r = rb_rational_plus(r, e);
}
else
goto not_exact;
}
v = finish_exact_sum(n, r, v, argc!=0);
return v;
not_exact:
v = finish_exact_sum(n, r, v, i!=0);
if (RB_FLOAT_TYPE_P(e)) {
/*
* Kahan-Babuska balancing compensated summation algorithm
* See http://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double f, c;
f = NUM2DBL(v);
c = 0.0;
goto has_float_value;
for (; i < RARRAY_LEN(ary); i++) {
double x, t;
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (RB_FLOAT_TYPE_P(e))
has_float_value:
x = RFLOAT_VALUE(e);
else if (FIXNUM_P(e))
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;
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);
else
c += ((x - t) + f);
f = t;
}
f += c;
return DBL2NUM(f);
not_float:
v = DBL2NUM(f);
}
goto has_some_value;
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
has_some_value:
v = rb_funcall(v, idPLUS, 1, e);
}
return v;
}