The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

zuexact

R-CMD-check coverage

zuexact computes sums of doubles exactly and rounds once, at the end. The result is the correctly rounded true sum. It does not depend on the order of the elements, on the platform, or on how R was built. It is built on Radford Neal’s xsum superaccumulators.

Base R’s sum() accumulates in long double. That is 80-bit on x86-64 Linux and Windows, but the same as double on Apple Silicon and on R built without long doubles. So the same call gives different answers on different machines:

sum(c(1e16, 1, -1e16))
#> 1 on x86-64 Linux and Windows
#> 0 on Apple Silicon

The exact answer is 1, everywhere, and xsum() returns it on every platform:

library(zuexact)
xsum(c(1e16, 1, -1e16))
#> [1] 1
xsum(c(1e20, 1, -1e20))      # wrong on every platform with sum()
#> [1] 1
xsum_mean(c(1e15, -1e15, 0.1))
#> [1] 0.03333333

Sums in pieces, and across processes

An accumulator holds an exact sum in progress. It is an ordinary R value, so an accumulator built on a worker comes back to the caller and merges there, in any order, with the same bits as summing everything at once:

chunks <- split(x, rep(1:8, length.out = length(x)))
accs <- parallel::mclapply(chunks, xsum_acc)
xsum_value(Reduce(xsum_merge, accs)) == xsum(x)
#> [1] TRUE

The same works for Arrow record batches, DuckDB result chunks or files read in pieces: acc <- xsum_add(acc, chunk) for each one, then xsum_value(acc). xsum_merge(a, xsum_negate(b)) is the exact difference of two sums.

What else is in the package

vignette("exact-summation") explains the details. For compensated summation (Kahan, Neumaier, pairwise), which is faster but not exact, see PreciseSums.

Installation

Install the released version from CRAN with:

install.packages("zuexact")

or the development version from GitHub with:

# install.packages("pak")
pak::pak("pedrobtz/zuexact")

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.