Home > Back-end >  Obtaining different results from sum() and ' '
Obtaining different results from sum() and ' '

Time:10-13

Below is my experiment:

> xx = 293.62882204364098
> yy = 0.086783439604999998
> print(xx   yy, 20)
[1] 293.71560548324595175
> print(sum(c(xx,yy)), 20)
[1] 293.71560548324600859

It is strange to me that sum() and giving different results when both are applied to the same numbers.

Is this result expected?

How can I get the same result?

Which one is most efficient?

CodePudding user response:

There is an r-devel thread here that includes some detailed description of the implementation. In particular, from Tomas Kalibera:

R uses long double type for the accumulator (on platforms where it is available). This is also mentioned in ?sum: "Where possible extended-precision accumulators are used, typically well supported with C99 and newer, but possibly platform-dependent."

This would imply that sum() is more accurate, although this comes with a giant flashing warning sign that if this level of accuracy is important to you, you should be very worried about the implementation of your calculations [in terms both of algorithms and underlying numerical implementations].

I answered a question here where I eventually figured out (after some false starts) that the difference between and sum() is due to the use of extended precision for sum().

This code shows that the sums of individual elements (as in sum(xx,yy) are added together with (in C), whereas this code is used to sum the individual components; line 154 (LDOUBLE s=0.0) shows that the accumulator is stored in extended precision (if available).

I believe that @JonSpring's timing results are probably explained (but would be happy to be corrected) by (1) sum(xx,yy) will have more processing, type-checking etc. than ; (2) sum(c(xx,yy)) will be slightly slower than sum(xx,yy) because it works in extended precision.

CodePudding user response:

Looks like addition is 3x as fast as summing, but unless you're doing high-frequency trading I can't see a situation where this would be your timing bottleneck.

xx = 293.62882204364098
yy = 0.086783439604999998

microbenchmark::microbenchmark(xx   yy, sum(xx,yy), sum(c(xx, yy)))
Unit: nanoseconds
           expr min    lq   mean median    uq  max neval
        xx   yy  88 102.5 111.90  107.0 110.0  352   100
    sum(xx, yy) 201 211.0 256.57  218.5 232.5 2886   100
 sum(c(xx, yy)) 283 297.5 330.42  304.0 311.5 1944   100

CodePudding user response:

Additional to the answer provided here I want to present my thinking: Here is an explanation how I made it clear to myself! Please clarify if I am wrong!

As far as I know this is because DOUBLE works with 53 bits (about 16 digits)

# both xx and yy are double type
typeof(print(xx   yy, 20))
typeof(print(sum(c(xx,yy)), 20))

# all values with after comma places > 16 will give different results
print(xx   yy, 17)
print(sum(c(xx,yy)), 17)

#[1] 293.71560548324595
#[1] 293.71560548324601

# all values with after comma places <= 16 will give identical results
print(xx   yy, 16)
print(sum(c(xx,yy)), 16)

#[1] 293.715605483246
#[1] 293.715605483246

# As far as I know this is because DOUBLE works with 53 bits (about 16 digits)
  •  Tags:  
  • r sum
  • Related