Skip to content
Prev 42056 / 63435 Next

bug in sum() on integer vector

Hi Peter,
On 11-12-14 08:19 AM, peter dalgaard wrote:
Since you want to generate this warning once only, your test (now
inside the loop) needs to be something like:

     if (warn && (s > INT_MAX || s < R_INT_MIN)) {
         generate the warning
         warn = 0;
     }

with 'warn' initialized to 1. This makes the isum() function almost
twice slower on my machine (64-bit Ubuntu) when compiling with
gcc -O2 and when no overflow occurs (the most common use case I guess).

Why not just do the sum in a long double instead of a double?
It slows down isum() by only 8% on my machine when compiling
with gcc -O2.
But most importantly this solution also has the advantage of making
sum(x) consistent with sum(as.double(x)). The latter uses rsum() which
does the sum in a long double. So by using a long double in both isum()
and rsum(), consistency between sum(x) and sum(as.double(x)) is
guaranteed.
Maybe that still doesn't give you the guarantee that sum(x) will always
return the correct value (when it does not return NA) because that
depends now on the ability of long double to represent exactly the sum
of at most INT_MAX arbitrary ints. The nb of bits used for long double
seems to vary a lot across platforms/compilers so it's hard to tell.
Not an ideal solution, but at least it makes isum() more accurate than
the current isum() and it makes sum(x) consistent with sum(as.double(x))
on all platforms, without degrading performance too much.

Cheers,
H.