从 sum() 和 '+' 中获得不同的结果

4

以下是我的实验:

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

当我将sum()+应用于相同的数字时,它们给出不同的结果,这对我来说很奇怪。

这个结果是否符合预期?

如何获得相同的结果?

哪一个更有效率?


浮点数精度相关的SO问题和答案:https://dev59.com/_Gkw5IYBdhLWcg3w_fiJ - Jon Spring
有趣的是,sum(xx,yy)xx+yy相同。另外,Reduce(\+`, c(xx,yy))也是一样的。只有sum(c(xx,yy))`不同。 - MrFlick
但是这种精度不应该以相同的方式影响sum+吗?这两者之间真正的区别是什么? - Bogaso
2个回答

5

这里有一个 r-devel 帖子,其中包含了一些实现的详细描述。特别是来自Tomas Kalibera的帖子:

R在累加器中使用了long double类型(在支持它的平台上)。这也在?sum中提到: “尽可能使用扩展精度累加器,通常使用C99及更高版本进行支持,但可能与平台相关。”

这意味着 sum() 更准确,虽然这带有一个巨大的警告标志,即如果这种精度对您很重要,您应该非常担心您计算的实现 [即算法和底层数值实现]。

我在这里回答了一个问题,最终我发现(经过一些错误的尝试)+sum() 的区别是由于 sum() 使用扩展精度导致的。

这段代码 显示单个元素的和(如 sum(xx,yy))是用 + 相加的(在C中),而这段代码 用于总和各个组件;第154行 (LDOUBLE s = 0.0) 表示累加器以扩展精度存储(如果可用)。

我认为 @JonSpring 的计时结果可能是由以下原因解释的(但也很乐意接受更正):(1) sum(xx,yy)+ 处理时间、类型检查等要长; (2) sum(c(xx,yy))sum(xx,yy) 稍慢一点,因为它使用扩展精度。


1
源代码实际上是一个名为do_summary的函数。它处理sum()min()max()prod() - MrFlick
我看到了,但是感到困惑...以为它与 summary() 有关。 - Ben Bolker
基本名称到c函数名的转换发生在names.c中。如果do_summarysummary()有关,那么这将是有意义的,但事实证明summary.default不是原始函数,所以所有工作都在R代码而不是C代码中完成。 - MrFlick
谢谢。那么为什么print(sum(c(xx,yy)), 20)print(sum(xx,yy, 20)不同? - Bogaso
sum(xx,yy,20) 相当于 sum(xx)+sum(yy)+20) - Ben Bolker

2

看起来加法比求和快3倍,但除非你在进行高频交易,否则我无法想象出这种情况会成为计时瓶颈。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接